{"record":{"id":"764d4f5efdfd773d","repo":"nocobase/nocobase","slug":"label-does-not-support-unknownkeys-join","errorCode":null,"errorMessage":"${label} does not support: ${unknownKeys.join(', ')}","messagePattern":"(.+?) does not support: (.+?)","errorType":"validation","errorClass":"FlowSurfaceBadRequestError","httpStatus":400,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-flow-engine/src/server/flow-surfaces/chart-config.ts","lineNumber":579,"sourceCode":"  return direction.toUpperCase();\n}\n\nfunction fromPersistedOrder(input: any) {\n  if (_.isUndefined(input) || _.isNull(input) || String(input).trim() === '') {\n    return undefined;\n  }\n  const normalized = String(input).trim().toLowerCase();\n  return CHART_SORT_DIRECTION_SET.has(normalized) ? normalized : undefined;\n}\n\nfunction createEmptyFilterGroup() {\n  return _.cloneDeep(FLOW_SURFACE_EMPTY_FILTER_GROUP);\n}\n\nfunction assertAllowedKeys(input: Record<string, any>, allowed: Set<string>, label: string) {\n  const unknownKeys = Object.keys(input).filter((key) => !allowed.has(key));\n  if (unknownKeys.length) {\n    throw new FlowSurfaceBadRequestError(`${label} does not support: ${unknownKeys.join(', ')}`);\n  }\n}\n\nfunction mergeReplaceArrays(base: any, patch: any) {\n  return _.mergeWith({}, _.cloneDeep(base || {}), _.cloneDeep(patch || {}), (_objValue, srcValue) => {\n    if (Array.isArray(srcValue)) {\n      return srcValue;\n    }\n    return undefined;\n  });\n}\n\nfunction normalizeChartResourceFromCollectionPath(\n  collectionPath: any,\n  label: string,\n  options: { required?: boolean } = {},\n) {\n  if (_.isUndefined(collectionPath) || _.isNull(collectionPath)) {","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-flow-engine/src/server/flow-surfaces/chart-config.ts#L561-L597","documentation":"assertAllowedKeys performs strict key checking on normalized chart config objects: any key not present in the allowed Set causes FlowSurfaceBadRequestError listing the unsupported keys. This blocks unknown/legacy fields from entering chart config.","triggerScenarios":"Submitting chart config objects containing extra properties (typo'd keys, deprecated fields, nested wrapper objects) to the chart config normalizers, e.g. normalizeBasicVisual with an unexpected key in the visual block.","commonSituations":"Configs copied from older plugin versions whose schema changed; hand-written JSON with typos ('lable' instead of 'label'); clients that forward whole form state including helper keys like 'id' or 'createdAt'.","solutions":["Remove the unsupported keys listed in the message before submitting","Check the current chart-config schema for the correct key names (typos are the usual cause)","Migrate deprecated keys to their current equivalents per the plugin's current version"],"exampleFix":"// before\nbasicVisual: { type: 'bar', colorScheme: 'default' } // colorScheme not supported\n// after\nbasicVisual: { type: 'bar' }","handlingStrategy":"validation","validationCode":"function pickAllowed(obj, allowedKeys) {\n  return Object.fromEntries(Object.entries(obj).filter(([k]) => allowedKeys.includes(k)));\n}\nconst payload = pickAllowed(basicVisual, ['type', 'title', 'legend', 'axes']);","typeGuard":"function hasOnlyKeys<T extends object>(obj: T, allowed: readonly (keyof T)[]): boolean {\n  return Object.keys(obj).every((k) => (allowed as string[]).includes(k));\n}","tryCatchPattern":"try {\n  await api.saveChartConfig(config);\n} catch (err) {\n  if (err instanceof FlowSurfaceBadRequestError && err.message.includes('does not support')) {\n    const bad = err.message.split(': ')[1]?.split(', ') ?? [];\n    bad.forEach((k) => delete config.basicVisual[k]);\n  }\n  throw err;\n}","preventionTips":["Strip metadata keys (id, createdAt, UI-only state) from payloads before submit","Keep client config types in sync with the plugin version after upgrades","Whitelist-and-forward rather than forwarding whole form state"],"tags":["validation","schema","strict-mode","chart-config","bad-request"],"backgroundTag":"unknown-config-key","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}