Fix: Can'

Error message:
Can'
Middleware & Endpoints 2025-01-25

What Causes This Error?

This error occurs when Astro cannot load your middleware file. Common causes include syntax errors, incorrect exports, wrong file location, or missing dependencies.

The Problem

// src/middleware.ts
// ❌ Syntax error
export const onRequest = (context, next) => {
  return next(
}
// ❌ Wrong export name
export const middleware = (context, next) => {
  return next();
}

The Fix

Correct File Location

src/
└── middleware.ts    # ✅ Must be in src/ root

Correct Export

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

// ✅ Export as onRequest
export const onRequest = defineMiddleware((context, next) => {
  return next();
});

Common Scenarios

Wrong File Location

# ❌ Wrong locations
src/pages/middleware.ts
src/lib/middleware.ts
middleware.ts

# ✅ Correct location
src/middleware.ts
# or
src/middleware.js

Missing Export

// ❌ Not exported
const onRequest = (context, next) => next();

// ✅ Must export
export const onRequest = (context, next) => next();

Wrong Export Name

// ❌ Wrong names
export const middleware = ...
export const handler = ...
export default ...

// ✅ Must be onRequest
export const onRequest = ...

Import Errors

// ❌ Module not found
import { something } from 'non-existent-package';

// ✅ Ensure dependencies are installed
npm install the-package

TypeScript Errors

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

// ❌ Type error
export const onRequest = defineMiddleware((context, next) => {
  const user: User = context.locals.user; // User type not defined
  return next();
});

// ✅ Define types properly
interface User {
  name: string;
}

export const onRequest = defineMiddleware((context, next) => {
  const user = context.locals.user as User;
  return next();
});

Circular Imports

// ❌ Circular dependency
// middleware.ts imports utils.ts
// utils.ts imports middleware.ts

// ✅ Restructure to avoid circles
// Extract shared code to a third file

Async Initialization

// ❌ Top-level await might cause issues
const config = await loadConfig();

export const onRequest = defineMiddleware((context, next) => {
  // ...
});

// ✅ Initialize inside the middleware
export const onRequest = defineMiddleware(async (context, next) => {
  const config = await loadConfig(); // Or use caching
  return next();
});

Sequence with Broken Middleware

import { sequence } from 'astro:middleware';
import { auth } from './middleware/auth';
import { logging } from './middleware/logging'; // ❌ This file has errors

// If any file has errors, sequence fails
export const onRequest = sequence(auth, logging);

Debug Loading Issues

// src/middleware.ts
console.log('Middleware loading...');

import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware((context, next) => {
  console.log('Middleware executing...');
  return next();
});

console.log('Middleware loaded');

Check Build Output

# Run build to see detailed errors
npm run build

# Or dev mode with verbose
DEBUG=astro:* npm run dev

Valid Middleware Structure

// src/middleware.ts
import { defineMiddleware, sequence } from 'astro:middleware';

// Simple middleware
export const onRequest = defineMiddleware((context, next) => {
  return next();
});

// Or with sequence
const first = defineMiddleware((ctx, next) => next());
const second = defineMiddleware((ctx, next) => next());

export const onRequest = sequence(first, second);

Quick Checklist

  • File is at src/middleware.ts (or .js)
  • Export is named onRequest
  • No syntax errors in the file
  • All imports resolve correctly
  • Use defineMiddleware wrapper
  • Check terminal for specific error messages