{"record":{"id":"ae33825bfa340086","repo":"facebook/relay","slug":"expected-operation-artifact-to-have-an-id-ensur","errorCode":null,"errorMessage":"Expected operation artifact to have an `id`. Ensure a `persistConfig` is setup for the current project.","messagePattern":"Expected operation artifact to have an `id`\\. Ensure a `persistConfig` is setup for the current project\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs","lineNumber":271,"sourceCode":"            typegen_operation: operations.expect_typegen(),\n            source_hash,\n            text,\n            id_and_text_hash: None,\n        },\n        source_file: normalization.name.location.source_location(),\n    }\n}\n\npub fn generate_preloadable_query_parameters_artifact(\n    project_config: &ProjectConfig,\n    normalization: &Arc<OperationDefinition>,\n    id_and_text_hash: &Option<QueryID>,\n    source_keys: Vec<ArtifactSourceKey>,\n    source_file: SourceLocationKey,\n) -> Artifact {\n    let query_id = id_and_text_hash\n        .clone()\n        .expect(\"Expected operation artifact to have an `id`. Ensure a `persistConfig` is setup for the current project.\");\n\n    let artifact_name = normalization.name.item.0.to_string() + \"$parameters\";\n\n    Artifact {\n        artifact_source_keys: source_keys,\n        path: project_config.path_for_language_specific_artifact(source_file, artifact_name),\n        content: ArtifactContent::PreloadableQueryParameters {\n            normalization_operation: Arc::clone(normalization),\n            query_id,\n        },\n        source_file,\n    }\n}\n\nfn generate_updatable_query_artifact(\n    artifact_source: ArtifactSourceKey,\n    project_config: &ProjectConfig,\n    operations: &OperationGroup<'_>,","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs#L253-L289","documentation":"generate_preloadable_query_parameters_artifact emits the `<query>$parameters.js` preloadable artifact, which requires the operation's persisted id. The id comes from id_and_text_hash, populated only when persistConfig/persisted-queries is set up; if it's None the expect panics instructing the developer to configure persistence.","triggerScenarios":"Enabling preloadable query generation (persisted queries) for a project whose relay config lacks persistConfig, so operations have text/hash but no persisted id at artifact generation time.","commonSituations":"Adding preloadable queries to an app that never configured persistConfig (e.g. @queryPersisted or a custom persister); migrating a project to persisted queries without setting up the persist pipeline; build generators expecting ids before running the persist step.","solutions":["Set up persistConfig in the project's relay config so operation ids are generated before artifacts","Ensure the persist step (id generation) runs before generate_artifacts, or run `relay persist-operations` as part of the build","If persistence is not intended, disable preloadable query artifact generation for the project"],"exampleFix":"// before (relay.config.js)\nmodule.exports = { src: \"./src\", schema: \"./schema.graphql\" };\n// after\nmodule.exports = {\n  src: \"./src\",\n  schema: \"./schema.graphql\",\n  persistConfig: { type: \"file\", file: \"./queryMap.json\" },\n};","handlingStrategy":"validation","validationCode":"const cfg = require('./relay.config.js');\nif (cfg.preloadableQueries && !cfg.persistConfig) {\n  throw new Error('Preloadable queries require persistConfig for persisted operation ids');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await relay(['build']);\n} catch (e) {\n  if (/Expected operation artifact to have an `id`/.test(e.message)) {\n    console.error('Add persistConfig to relay.config.js or disable preloadable query artifacts.');\n  } else throw e;\n}","preventionTips":["Configure persistConfig whenever using preloadable/persisted queries","Ensure the persist/id-generation step runs before artifact generation","Run `relay persist-operations` in the build pipeline","Audit relay.config.js when migrating to persisted queries"],"tags":["persisted-queries","config","artifact-generation","panic"],"backgroundTag":"missing-persist-config","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}