Change:
Code in the doesn't seem to be evaluated in production for Cash Register project. (Edit)This appear to be related to the code saving / resetting. In development there isn't such issue. Including building production client and serving it. This is actually the only challenge from the new challenges that is using . Old challenges are working fine when using . Both when names start with ` might be somehow deciding factor, but there isn't any other new challenge to check that. After adding function to user code, error moves normally to the next used in test non-defined variable - and then . Steps to reproduce the behavior: (Be logged in, and have previously saved code for project). to solution. Example: tests. errors. Code present in the should be evaluated after the user code, and before running tests. (Edit) When logged out there's different error, or no errors at all(?!). This might be somehow related to saving / resetting code.
Thanks again for the detailed report, You were dead right about the issue: it's due to the fact that saved challenges don't include head or tail (aka and ) and we were just using them in place of challengeFiles (which does have that stuff).
I have marked this as a showstopper seeing as it is affecting camper's ability to complete a certificate project. It would be nice to get the fix in as soon as possible, so the forum isn't filled with support threads for this.

Discussion:
challengeFiles: SavedChallengeFiles; }; <ins> // TODO: remove unused properties and stop returning them from api? (e.g. // history, ext, name) </ins> export type SavedChallengeFile = { fileKey: string; ext: Ext;

<ins> import type { ChallengeFile, SavedChallengeFile } from '../../../redux/prop-types'; import { mergeChallengeFiles } from './saved-challenges'; const jsChallenge = { id: '1', contents: 'js contents', fileKey: 'jsFileKey', name: 'name', ext: 'js' as const, head: 'head', tail: 'tail', history: [], seed: 'original js contents' }; const cssChallenge = { id: '2', contents: 'css contents', fileKey: 'cssFileKey', name: 'name', ext: 'css' as const, head: 'head', tail: 'tail', history: [], seed: 'original css contents' }; const htmlChallenge = { id: '3', contents: 'html contents', fileKey: 'htmlFileKey', name: 'name', ext: 'html' as const, head: 'head', tail: 'tail', history: [], seed: 'original html contents' }; const savedJsChallenge: SavedChallengeFile = { contents: 'saved js contents', fileKey: 'jsFileKey', name: 'name', ext: 'js' as const }; const savedCssChallenge: SavedChallengeFile = { contents: 'saved css contents', fileKey: 'cssFileKey', name: 'name', ext: 'css' as const }; const savedHtmlChallenge: SavedChallengeFile = { contents: 'saved html contents', fileKey: 'htmlFileKey', name: 'name', ext: 'html' as const }; describe('mergeChallengeFiles', () => { it('should return files if savedChallengeFiles is undefined', () => { const files: ChallengeFile[] = [htmlChallenge]; const savedChallengeFiles = undefined; const result = mergeChallengeFiles(files, savedChallengeFiles); expect(result).toEqual(files); }); it('should return an empty array if files is undefined', () => { const files = undefined; const savedChallengeFiles = [savedJsChallenge]; const result = mergeChallengeFiles(files, savedChallengeFiles); expect(result).toEqual([]); }); it('should return files if savedChallengeFiles has a different length', () => { const files: ChallengeFile[] = [cssChallenge]; const savedChallengeFiles: SavedChallengeFile[] = [ savedCssChallenge, savedJsChallenge ]; const result = mergeChallengeFiles(files, savedChallengeFiles); expect(result).toEqual(files); }); it('should return files if the fileKey properties do not match', () => { const files: ChallengeFile[] = [jsChallenge, cssChallenge]; const savedChallengeFiles: SavedChallengeFile[] = [ savedHtmlChallenge, savedCssChallenge ]; const result = mergeChallengeFiles(files, savedChallengeFiles); expect(result).toEqual(files); }); it('should use the contents from the saved file', () => { const files: ChallengeFile[] = [cssChallenge, htmlChallenge, jsChallenge]; const savedChallengeFiles = [ savedJsChallenge, savedCssChallenge, savedHtmlChallenge ]; const result = mergeChallengeFiles(files, savedChallengeFiles); expect(result).toEqual([ { ...cssChallenge, contents: savedCssChallenge.contents }, { ...htmlChallenge, contents: savedHtmlChallenge.contents }, { ...jsChallenge, contents: savedJsChallenge.contents } ]); }); }); </ins>

<ins> import { ChallengeFile, SavedChallengeFile } from '../../../redux/prop-types'; export function mergeChallengeFiles( files?: ChallengeFile[] | null, savedFiles?: SavedChallengeFile[] | null ): ChallengeFile[] { if (!files) return []; if (!savedFiles) return files; if (files.length !== savedFiles.length) return files; const sortedChallengeFiles = files.sort((a, b) => a.fileKey.localeCompare(b.fileKey) ); const sortedSavedChallengeFiles = savedFiles.sort((a, b) => a.fileKey.localeCompare(b.fileKey) ); const fileKeysMatch = sortedChallengeFiles.every( (file, index) => file.fileKey === sortedSavedChallengeFiles[index].fileKey ); if (!fileKeysMatch) return files; return sortedChallengeFiles.map((file, index) => ({ ...file, contents: sortedSavedChallengeFiles[index].contents })); } </ins>

import MultifileEditor from './multifile-editor'; import DesktopLayout from './desktop-layout'; import MobileLayout from './mobile-layout'; <ins> import { mergeChallengeFiles } from './saved-challenges'; </ins> import './classic.css'; import '../components/test-frame.css';

return challenge.id === challengeMeta.id; }); <del> createFiles(savedChallenge?.challengeFiles || challengeFiles || []); </del> <ins> createFiles( mergeChallengeFiles(challengeFiles, savedChallenge?.challengeFiles) ); </ins> initTests(tests); if (showProjectPreview) openModal('projectPreview');