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

  1. Find the transform that produces Primitive::RawString for the affected argument and use Primitive::String (an actual literal) instead
  2. Replace the raw-string content with a proper literal value in the document/argument (quote it as a real string)
  3. Verify the value path: strings intended for output should use Primitive::String, not RawString
  4. 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

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


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/313b8f2989a34709. Report an issue: GitHub.