{"record":{"id":"bf6f2d7b6f74ddb4","repo":"windmill-labs/windmill","slug":"invalid-key","errorCode":null,"errorMessage":"Invalid key","messagePattern":"Invalid key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/apps/components/helpers/eval.ts","lineNumber":151,"sourceCode":"\trunnableComponents: Record<string, { cb?: (() => void)[] }>,\n\tnoReturn: boolean,\n\tgroupContextId: string | undefined,\n\tglobalRecomputeFunction: ((excludeIds?: string) => void) | undefined\n) {\n\tconst createProxy = (name: string, obj: any) => {\n\t\t// console.log('Creating proxy', name, obj)\n\t\tif (obj != null && obj != undefined && typeof obj == 'object') {\n\t\t\tif (name == 'group' && groupContextId) {\n\t\t\t\treturn createGroupProxy(groupContextId, obj)\n\t\t\t}\n\t\t\treturn new Proxy(obj, {\n\t\t\t\tset(target, key, value) {\n\t\t\t\t\tif (name != 'state') {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Cannot set value on objects that are neither the global state or a container group field'\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof key !== 'string') {\n\t\t\t\t\t\tthrow new Error('Invalid key')\n\t\t\t\t\t}\n\t\t\t\t\ttarget[key] = value\n\t\t\t\t\tlet o = worldStore?.newOutput(name, key, value)\n\t\t\t\t\to?.set(value, true)\n\n\t\t\t\t\treturn true\n\t\t\t\t},\n\t\t\t\tget(obj, prop) {\n\t\t\t\t\tif (name != 'state' && prop == 'group') {\n\t\t\t\t\t\treturn createGroupProxy(name, obj[prop])\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn obj[prop]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\treturn obj","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/apps/components/helpers/eval.ts#L133-L169","documentation":"The same eval sandbox Proxy for the global state validates that every assigned key is a string before writing it and syncing the value into the World store. Symbol or non-string keys (e.g. from programmatic/spread logic, Symbol.iterator, or obfuscated expression code) throw 'Invalid key'.","triggerScenarios":"Assigning a computed property with a Symbol key to state inside an app expression, e.g. `state[symbolKey] = v`, or library/user code that runs Object.assign-like logic with symbol keys against the state proxy, or numeric keys coerced from exotic paths.","commonSituations":"Using spread or utility functions that copy symbols onto state; defining custom Symbol.toPrimitive/iterator interactions on objects assigned into state; writing expression code with dynamic bracket access where the key evaluates to a symbol.","solutions":["Use string keys only: ensure the key expression evaluates to a string, e.g. `state[String(key)] = value`","Check for accidental symbol-key assignment (Symbol.iterator, Symbol.asyncIterator) — spread those objects explicitly instead","If copying objects, assign the whole object once (`state.items = obj`) rather than copying its keys individually"],"exampleFix":"// before\nstate[myKey] = value // myKey may be a symbol\n// after\nif (typeof myKey !== 'string') throw new Error('state keys must be strings')\nstate[myKey] = value","handlingStrategy":"validation","validationCode":"if (typeof key !== 'string') {\n  throw new Error(`state keys must be strings, got ${typeof key}`)\n}\nstate[key] = value","typeGuard":"function isStringKey(key: PropertyKey): key is string {\n  return typeof key === 'string'\n}","tryCatchPattern":"try {\n  state[key] = value\n} catch (e) {\n  if (e.message === 'Invalid key') {\n    state[String(key)] = value\n  } else throw e\n}","preventionTips":["Never use Symbol or non-string keys when writing to app state","Avoid spreading objects with symbol keys directly onto the state proxy","Coerce dynamic keys with String(key) or template literals before assignment","Keep state writes simple and literal in expression handlers to stay within the sandbox's assumptions"],"tags":["windmill-apps","eval","proxy","invalid-key","frontend"],"backgroundTag":"read-only-context-mutation","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}