{"record":{"id":"3e81f5514f7cdb8c","repo":"withastro/astro","slug":"incorrectstrategyfori18n","errorCode":"IncorrectStrategyForI18n","errorMessage":"The function `${functionName}` can only be used when the `i18n.routing.strategy` is set to `\"manual\"`.","messagePattern":"The function `(.+?)` can only be used when the `i18n\\.routing\\.strategy` is set to `\"manual\"`\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/virtual-modules/i18n.ts","lineNumber":35,"sourceCode":"import type { MiddlewareHandler } from '../types/public/common.js';\nimport type { AstroConfig, ValidRedirectStatus } from '../types/public/config.js';\nimport type { APIContext } from '../types/public/context.js';\nimport type { ClientDeserializedManifest } from '../types/public/index.js';\n\nconst { trailingSlash, site, i18n, build } = config as ClientDeserializedManifest;\nconst { format } = build;\nconst isBuild = import.meta.env.PROD;\nconst { defaultLocale, locales, domains, fallback, routing } = i18n!;\nconst base = import.meta.env.BASE_URL;\n\nlet strategy = toRoutingStrategy(routing, domains);\nlet fallbackType = toFallbackType(routing);\n\nexport type GetLocaleOptions = I18nInternals.GetLocaleOptions;\n\nconst noop = (method: string) =>\n\tfunction () {\n\t\tthrow new AstroError({\n\t\t\t...IncorrectStrategyForI18n,\n\t\t\tmessage: IncorrectStrategyForI18n.message(method),\n\t\t});\n\t};\n\n/**\n * @param locale A locale\n * @param path An optional path to add after the `locale`.\n * @param options Customise the generated path\n *\n * Returns a _relative_ path with passed locale.\n *\n * ## Errors\n *\n * Throws an error if the locale doesn't exist in the list of locales defined in the configuration.\n *\n * ## Examples\n *","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/virtual-modules/i18n.ts#L17-L53","documentation":"Several exports of the astro:i18n virtual module — middleware, notFound, requestHasLocale, redirectToDefaultLocale, and redirectToFallback — exist only when you take full control of routing by setting i18n.routing to \"manual\" in astro.config. With any other routing configuration these functions are replaced with stubs that throw IncorrectStrategyForI18n, naming the function you called. This is intentional: with automatic routing Astro handles these concerns, so the manual APIs do not apply.","triggerScenarios":"Calling middleware(...) from astro:i18n in src/middleware.ts while i18n.routing is unset or set to an options object; calling redirectToDefaultLocale(context), notFound(context), requestHasLocale(context), or redirectToFallback(...) under non-manual routing.","commonSituations":"Copy-pasting the manual i18n middleware example from the docs without switching routing to 'manual'; migrating configs across Astro majors where routing options moved between string and object forms.","solutions":["Set i18n: { routing: 'manual' } in astro.config.mjs if you truly want to drive routing yourself","Otherwise remove the manual-only calls and let automatic routing plus fallback configuration handle it","If you keep automatic routing but need custom logic, write a normal src/middleware.ts without the astro:i18n helpers"],"exampleFix":"// before — astro.config.mjs\nexport default defineConfig({\n\ti18n: { defaultLocale: 'en', locales: ['en', 'es'], routing: { prefixDefaultLocale: true } },\n});\n\n// after\nexport default defineConfig({\n\ti18n: { defaultLocale: 'en', locales: ['en', 'es'], routing: 'manual' },\n});","handlingStrategy":"validation","validationCode":"// astro.config.mjs — fail at config load instead of at request time\nconst config = defineConfig({\n\ti18n: { defaultLocale: 'en', locales: ['en', 'es'], routing: 'manual' },\n});\n// middleware(), notFound(), requestHasLocale(), redirectToDefaultLocale(),\n// redirectToFallback() from 'astro:i18n' all require routing: 'manual'\nif (config.i18n?.routing !== 'manual' && process.env.ASTRO_I18N_MANUAL_HELPERS) {\n\tthrow new Error('astro:i18n manual helpers require i18n.routing: \"manual\"');\n}","typeGuard":"const isManualI18nRouting = (routing: unknown): routing is 'manual' => routing === 'manual';","tryCatchPattern":null,"preventionTips":["Set i18n.routing: 'manual' in astro.config before importing the manual helpers from astro:i18n","With automatic routing, do not call middleware/notFound/requestHasLocale/redirectToDefaultLocale/redirectToFallback at all","Add a comment in src/middleware.ts noting which routing mode it assumes"],"tags":["i18n","routing","middleware","config"],"backgroundTag":"i18n-routing-misconfigured","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}