facebook/relay · error
Babel state is missing expected file name
Error message
Babel state is missing expected file name
What it means
getRelativeImportPath needs the current source file's path (state.file.opts.filename) to compute a relative require path from the file to the generated artifact directory. If state.file is null the Babel state is malformed, so the plugin cannot determine where the importing file lives and throws. This is an environment/tooling failure, not a user GraphQL mistake.
Source
Thrown at packages/babel-plugin-relay/compileGraphQLTag.js:247
t.memberExpression(t.identifier('console'), t.identifier('error')),
[
t.stringLiteral(
`The definition of '${definitionName}' appears to have changed. Run ` +
'`' +
buildCommand +
'` to update the generated files to receive the expected data.',
),
],
);
}
function getRelativeImportPath(
state: BabelState,
artifactDirectory: string,
fileToRequire: string,
): string {
if (state.file == null) {
throw new Error('Babel state is missing expected file name');
}
const filename = state.file.opts.filename;
const relative = relativePath(
dirname(filename),
resolvePath(artifactDirectory),
);
const relativeReference =
relative.length === 0 || !relative.startsWith('.') ? './' : '';
return relativeReference + joinPath(relative, fileToRequire);
}
module.exports = compileGraphQLTag;
View on GitHub (pinned to 668b1b85e0)
Solutions
- Ensure transforms run through @babel/core's normal pipeline so state.file is populated
- If invoking programmatically, construct a proper state including file and file.opts.filename
- Update babel-plugin-relay and @babel/core to compatible versions
- Check other Babel plugins that mutate or strip state.file earlier in the plugin list
Example fix
// before (custom transform with bare state)
plugin({ types: t }, { file: null });
// after (transform via @babel/core)
require('@babel/core').transform(code, {
filename: '/project/src/Component.js',
plugins: ['babel-plugin-relay'],
}); Defensive patterns
Strategy: validation
Validate before calling
function assertBabelStateHasFile(state) {
if (!state || !state.file || !state.file.opts || !state.file.opts.filename) {
throw new Error('Babel state must include file.opts.filename for babel-plugin-relay');
}
} Type guard
const hasFileState = (state) => !!state && !!state.file && !!state.file.opts && typeof state.file.opts.filename === 'string';
Prevention
- Run all transforms through the standard @babel/core pipeline
- When scripting transforms, always pass filename in babel transform options
- Keep Babel and plugin versions aligned to avoid state shape changes
When it happens
Trigger: Babel invokes the plugin with a state lacking state.file — e.g. custom transform scripts calling the plugin programmatically, some plugin-ordering or caching setups, or tools that fabricate a minimal state without file metadata.
Common situations: Custom Babel wrappers or AST transformers (e.g. codegen tools) that call the plugin with a synthetic state; newer/older Babel versions where state.file shape changed; running transforms outside the normal @babel/core pipeline.
Related errors
- BabelPluginRelay: Expected plugin context to include "types"
- BabelPluginRelay: Expected exactly one definition per graphq
- BabelPluginRelay: Expected a fragment, mutation, query, or s
- GraphQL operations and fragments must contain names
- BabelPluginRelay: Substitutions are not allowed in graphql f
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/7070b596d8dd1143.
Report an issue: GitHub.