{"record":{"id":"1ea8804cc6a4c8d2","repo":"Budibase/budibase","slug":"you-can-t-make-field-name-readonly-because-it","errorCode":null,"errorMessage":"You can't make \"${field.name}\" readonly because it is a required field.","messagePattern":"You can't make \"(.+?)\" readonly because it is a required field\\.","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/views/index.ts","lineNumber":318,"sourceCode":"    const viewSchemaField = view.schema?.[field.name]\n    const existingViewSchema = existingView?.schema?.[field.name]\n    if (!viewSchemaField && !existingViewSchema?.visible) {\n      // Supporting existing configs with required columns but hidden in views\n      continue\n    }\n\n    if (!viewSchemaField?.visible) {\n      throw new HTTPError(\n        `You can't hide \"${field.name}\" because it is a required field.`,\n        400\n      )\n    }\n\n    if (\n      helpers.views.isBasicViewField(viewSchemaField) &&\n      viewSchemaField.readonly\n    ) {\n      throw new HTTPError(\n        `You can't make \"${field.name}\" readonly because it is a required field.`,\n        400\n      )\n    }\n  }\n}\n\nexport async function create(\n  tableId: string,\n  viewRequest: Omit<ViewV2, \"id\" | \"version\">\n): Promise<ViewV2> {\n  await guardViewSchema(tableId, viewRequest)\n  const view = await pickApi(tableId).create(tableId, viewRequest)\n\n  // Set permissions to be the same as the table\n  const tablePerms = await sdk.permissions.getResourcePerms(tableId)\n  await sdk.permissions.setPermissions(view.id, {\n    writeRole: tablePerms[PermissionLevel.WRITE].role,","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/views/index.ts#L300-L336","documentation":"checkRequiredFields also forbids marking required fields as readonly in a view: a basic view field with readonly true on a required table column throws a 400 HTTPError, because users must be able to edit required values.","triggerScenarios":"create/update via guardViewSchema where helpers.views.isBasicViewField(viewSchemaField) and viewSchemaField.readonly === true for a table field that is required.","commonSituations":"Locking required columns in the builder UI; scripts that set readonly on all fields uniformly; copying view config from a table where the field wasn't required.","solutions":["Set readonly: false for that field in the view schema.","Remove the required constraint from the table field if it should be read-only.","Change the field to a non-basic field type if appropriate (non-basic fields bypass this check)."],"exampleFix":"// before\nview.schema[\"title\"].readonly = true // title is required\n// after\nview.schema[\"title\"].readonly = false","handlingStrategy":"validation","validationCode":"for (const f of Object.keys(table.schema)) {\n  if (table.schema[f].constraints?.required && view.schema?.[f]?.readonly) {\n    view.schema[f].readonly = false\n  }\n}","typeGuard":"function requiredFieldsEditable(view: ViewV2, table: Table): boolean {\n  return Object.entries(table.schema).every(([name, f]) =>\n    !(f.constraints?.required && view.schema?.[name]?.readonly === true))\n}","tryCatchPattern":"try {\n  await sdk.views.update(view)\n} catch (e) {\n  if (e instanceof HTTPError && e.status === 400 && e.message.includes(\"readonly because it is a required field\")) {\n    // set readonly:false or drop required constraint, then retry\n  } else { throw e }\n}","preventionTips":["Check constraints.required before marking fields readonly","Don't blanket-apply readonly across all view fields","Sync readonly flags with table constraint changes"],"tags":["validation","views","schema"],"backgroundTag":"invalid-view-configuration","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}