facebook/relay · error

Failed to build programs

Error message

Failed to build programs

What it means

run_codemod receives an Option<Arc<Programs>> that was produced by an earlier build step. For MarkDangerousConditionalFragmentSpreads it unwraps with .expect("Failed to build programs"), meaning the programs failed to construct earlier (compile errors, config problems) and the codemod cannot run.

Source

Thrown at compiler/crates/relay-codemod/src/codemod.rs:61

#[derive(Args, Debug, Clone)]
pub struct MarkDangerousConditionalFragmentSpreadsArgs {
    /// Specify a percentage of fragments to codemod. If a number is provided,
    /// the first n percentage of fragments will be codemodded. If a range (`20-30`) is
    /// provided, then fragments between the start and end of the range will be codemodded.
    #[clap(long, short, value_parser=valid_percent, default_value = "100")]
    pub rollout_percentage: FeatureFlag,
}

pub async fn run_codemod(
    programs: CompilerResult<Vec<Arc<Programs>>>,
    root_dir: PathBuf,
    codemod: AvailableCodemod,
) -> Result<(), std::io::Error> {
    match &codemod {
        AvailableCodemod::MarkDangerousConditionalFragmentSpreads(opts) => {
            run_codemod_impl(
                programs.expect("Failed to build programs"),
                root_dir,
                |programs: &Arc<Programs>| {
                    fragment_alias_directive(&programs.source, &opts.rollout_percentage).map(|_| ())
                }, // Codemods don't return anything for OK,
                format!("{codemod:?}").as_str(),
            )
            .await
        }
        AvailableCodemod::RemoveUnnecessaryRequiredDirectives => {
            run_codemod_impl(
                programs.expect("Failed to build programs"),
                root_dir,
                |programs: &Arc<Programs>| disallow_required_on_non_null_field(&programs.reader),
                format!("{codemod:?}").as_str(),
            )
            .await
        }
        AvailableCodemod::FixAll => {

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Run `relay build` (or the compiler) first and fix all reported GraphQL/schema errors until compilation succeeds
  2. Re-run the codemod after the build succeeds
  3. If running programmatically, check the build result before calling run_codemod instead of relying on expect

Example fix

// before
relay codemod mark-dangerous-conditional-fragment-spreads   // broken schema
// after
relay build            # fix errors it reports
relay codemod mark-dangerous-conditional-fragment-spreads
Defensive patterns

Strategy: try-catch

Validate before calling

// Run the compiler first and confirm success before codemod
const build = spawnSync('relay', ['build'], { stdio: 'inherit' });
if (build.status !== 0) throw new Error('Fix compiler errors before running codemods');

Try / catch

try {
  await runCodemod(rootDir, codemod, programs);
} catch (e) {
  if (/Failed to build programs/.test(e.message)) {
    console.error('Programs failed to build; run `relay build` and fix GraphQL/schema errors first.');
  } else throw e;
}

Prevention

When it happens

Trigger: Running the mark-dangerous-conditional-fragment-spreads codemod when the preceding program build returned None/Err, so the Option is unwrapped via expect.

Common situations: GraphQL syntax errors in the project that abort program construction; schema file changes that no longer parse; codemod run before fixing a broken compilation state.

Related errors


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