facebook/relay · error
Unexpected RawString
Error message
Unexpected RawString
What it means
write_constant_value handles only constant-printable Primitives; Primitive::RawString is an internal marker (raw code emitted verbatim, typically as a top-level statement or via a dedicated writer) that is invalid inside a constant value such as an argument literal. Encountering it in write_constant_value means a RawString leaked into literal printing, so the printer panics.
Source
Thrown at compiler/crates/relay-codegen/src/printer.rs:931
for ObjectEntry { key: name, value } in obj {
write!(f, "\\\"{name}\\\":")?;
write_constant_value(f, builder, value)?;
f.push(',');
}
if !obj.is_empty() {
f.pop();
}
f.push('}');
Ok(())
}
}
}
Primitive::Null | Primitive::SkippableNull => {
f.push_str("null");
Ok(())
}
Primitive::StorageKey(_, _) => panic!("Unexpected StorageKey"),
Primitive::RawString(_) => panic!("Unexpected RawString"),
Primitive::GraphQLModuleDependency(_) => panic!("Unexpected GraphQLModuleDependency"),
Primitive::JSModuleDependency { .. } => panic!("Unexpected JSModuleDependency"),
Primitive::ResolverModuleReference { .. } => panic!("Unexpected ResolverModuleReference"),
Primitive::PropertyAccessor(_) => panic!("Unexpected PropertyAccessor"),
Primitive::DynamicImport { .. } => panic!("Unexpected DynamicImport"),
Primitive::RelayResolverModel { .. } => panic!("Unexpected RelayResolver"),
}
}
View on GitHub (pinned to 668b1b85e0)
Solutions
- Find the transform that produces Primitive::RawString for the affected argument and use Primitive::String (an actual literal) instead
- Replace the raw-string content with a proper literal value in the document/argument (quote it as a real string)
- Verify the value path: strings intended for output should use Primitive::String, not RawString
- If on a patched/older compiler, update to a release where this invariant holds
Example fix
// before
Primitive::RawString("hello".to_string()) // in an argument value
// after
Primitive::String("hello".to_string()) Defensive patterns
Strategy: validation
Validate before calling
// Ensure string arguments are real literals:
function assertLiteralStrings(doc) {
visit(doc, {
Argument(node) {
if (node.value.kind === 'StringValue' && node.value.block && node.value.value.includes('\n')) {
throw new Error(`Use a normal StringValue for argument ${node.name.value}`);
}
}
});
} Type guard
const isPrintableConstant = (p) => p.kind !== 'RawString';
Try / catch
try {
generateArtifacts();
} catch (e) {
if (String(e).includes('Unexpected RawString')) {
// replace RawString with a proper String literal in the transform
}
throw e;
} Prevention
- Use Primitive::String (not RawString) for argument value content
- Only use RawString in writers that handle raw code emission
- Review custom transforms before merging into codegen paths
- Compile all documents in CI to catch invariant breaks early
When it happens
Trigger: Printing an argument or embedded constant whose builder produced Primitive::RawString — e.g. raw string artifacts injected into lists/objects/arguments instead of the intended string literal (Primitive::String); custom transform inserting raw code into a value position.
Common situations: Custom IR transforms or patched codegen that emit RawString for dynamic code inside arguments; builder misuse when constructing Primitives for arguments; compiler version drift where a RawString is produced where String is expected.
Related errors
- Unexpected StorageKey
- Unexpected GraphQLModuleDependency
- Unexpected JSModuleDependency
- Unexpected ResolverModuleReference
- Unexpected PropertyAccessor
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/313b8f2989a34709.
Report an issue: GitHub.