freeCodeCamp/freeCodeCamp · error · Error

No challenge files provided

Error message

No challenge files provided

What it means

Thrown by buildPythonChallenge in the challenge-builder package when it is dispatched without source files. Python challenges are built by piping every entry of challengeFiles through getPythonTransformers(), so the function guards its input first and throws synchronously when challengeFiles is undefined or null rather than producing an empty build. BuildChallengeData types the field as optional (challengeFiles?), so TypeScript does not flag the missing field at the call site.

Source

Thrown at packages/challenge-builder/src/build.ts:321

      .join('\n'),
    sources: buildSourceMap(finalFiles),
    error
  };
}

function buildBackendChallenge({ url, challengeType }: BuildChallengeData) {
  return {
    challengeType,
    build: '',
    sources: { contents: url }
  };
}

async function buildPythonChallenge({
  challengeFiles,
  challengeType
}: BuildChallengeData): Promise<BuildResult> {
  if (!challengeFiles) throw new Error('No challenge files provided');
  const pipeLine = composeFunctions(
    ...(getPythonTransformers() as unknown as ApplyFunctionProps[])
  );
  const finalFiles = await Promise.all(challengeFiles.map(pipeLine));
  const error = finalFiles.find(({ error }) => error)?.error;
  const sources = buildSourceMap(finalFiles);

  return {
    challengeType,
    sources,
    build: sources?.contents,
    error
  };
}

View on GitHub (pinned to 4289125977)

Solutions

  1. Pass the sources in: buildPythonChallenge({ challengeType, challengeFiles }) with a populated ChallengeFile[] (fileKey, path, contents).
  2. Log the incoming challenge object right before dispatch when challengeFiles is missing, to identify which curriculum record is malformed.
  3. Check the upstream mapping that builds BuildChallengeData - confirm the key name is challengeFiles and the array survives parsing.
  4. If missing files is legitimate for some types, branch in the dispatcher before calling buildPythonChallenge instead of relying on the throw.

Example fix

// before
buildPythonChallenge({ challengeType });
// after
buildPythonChallenge({ challengeType, challengeFiles });
Defensive patterns

Strategy: validation

Validate before calling

const files = challenge.challengeFiles;
if (!Array.isArray(files) || files.length === 0) {
  throw new Error('Python challenge ' + challenge.id + ' has no challengeFiles');
}
return buildPythonChallenge({
  challengeType: challenge.challengeType,
  challengeFiles: files
});

Type guard

type BuildablePythonData = BuildChallengeData & {
  challengeFiles: NonNullable<BuildChallengeData['challengeFiles']>;
};

const hasPythonFiles = (
  data: BuildChallengeData
): data is BuildablePythonData => Array.isArray(data.challengeFiles);

Try / catch

try {
  const result = await buildChallenge(challenge);
} catch (err) {
  if (err instanceof Error && err.message === 'No challenge files provided') {
    logger.warn({ id: challenge.id }, 'skipped: challenge has no files');
    continue;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling buildChallenge or buildPythonChallenge with an object whose challengeFiles key is absent, null, or undefined - for example buildPythonChallenge({ challengeType: 28 }). In practice: the curriculum or database record for a Python challenge ships no files, a data-loading step drops or renames the field (files vs challengeFiles), or a newly routed Python challengeType reaches this builder although its data shape has no files.

Common situations: Adding a new Python-based challengeType to the dispatcher without confirming its curriculum objects carry files; ingesting challenge JSON whose property is named differently; destructuring or optional-chaining mistakes producing undefined. The sibling buildJsChallenge has the same guard (build.ts:284), so refactors often hit both.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of freeCodeCamp/freeCodeCamp@4289125977 (2026-08-24). Data as JSON: /api/errors/ad2cf0b7fbab65c1. Report an issue: GitHub.