{"record":{"id":"1bf520d042c9423d","repo":"Budibase/budibase","slug":"custom-rest-templates-can-only-be-associated-with","errorCode":null,"errorMessage":"Custom REST templates can only be associated with REST datasources","messagePattern":"Custom REST templates can only be associated with REST datasources","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/query/index.ts","lineNumber":149,"sourceCode":"      },\n    })\n    await saveDatasource(datasourceCtx)\n    datasourceId = datasourceCtx.body.datasource._id\n  } else {\n    if (body.restTemplateId) {\n      await sdk.restTemplates.withCustomRestTemplateLock({\n        resource: body.restTemplateId,\n        task: async () => {\n          const templateExists = await sdk.restTemplates.exists(\n            body.restTemplateId!\n          )\n          if (!templateExists) {\n            throw new HTTPError(\"Custom REST template not found\", 404)\n          }\n\n          const datasource = await sdk.datasources.get(body.datasourceId!)\n          if (datasource.source !== SourceName.REST) {\n            throw new HTTPError(\n              \"Custom REST templates can only be associated with REST datasources\",\n              400\n            )\n          }\n          importer.prepareDatasourceConfig(datasource)\n          datasource.restTemplateId = body.restTemplateId\n          const response = await context\n            .getWorkspaceDB()\n            .put(sdk.tables.populateExternalTableSchemas(datasource))\n          datasource._rev = response.rev\n          await events.datasource.updated(datasource)\n          builderSocket?.emitDatasourceUpdate(ctx, datasource)\n        },\n      })\n    }\n    // use existing datasource\n    datasourceId = body.datasourceId\n  }","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/query/index.ts#L131-L167","documentation":"During `_import`, after verifying the template exists, the target datasource is fetched and its `source` must equal `SourceName.REST`. Associating a custom REST (OpenAPI) template with a datasource of any other type (e.g. PostgreSQL, MongoDB) throws this 400 HTTPError, since template import only makes sense for REST datasources.","triggerScenarios":"Calling the import endpoint with a `datasourceId` pointing to a non-REST datasource (SQL, Mongo, etc.) while also passing a `restTemplateId`.","commonSituations":"Wrong datasource selected in the import dialog; mixing up datasource IDs between apps; scripting the import against the wrong ID; UI bug passing the wrong resource to the request.","solutions":["Create or select a REST datasource and use its `datasourceId` in the request","Verify `datasource.source === \"REST\"` before calling the import endpoint","Check that the datasourceId is not from a different app or resource type"],"exampleFix":"// before\nawait importRestTemplate({ restTemplateId: id, datasourceId: pgDatasource._id })\n// after\nconst ds = await getDatasource(restDatasourceId)\nif (ds.source !== \"REST\") throw new Error(\"Need a REST datasource\")\nawait importRestTemplate({ restTemplateId: id, datasourceId: restDatasource._id })","handlingStrategy":"validation","validationCode":"const ds = await getDatasource(datasourceId)\nif (ds.source !== \"REST\") {\n  throw new Error(\"Custom REST templates require a REST datasource\")\n}","typeGuard":"const isRestDatasource = (ds) => ds.source === \"REST\"","tryCatchPattern":"try {\n  await importRestTemplate({ restTemplateId, datasourceId })\n} catch (e) {\n  if (e.status === 400 && String(e.message).includes(\"only be associated with REST datasources\")) {\n    // prompt user to pick a REST datasource\n  }\n}","preventionTips":["Fetch the datasource and check its `source` field before importing","Ensure the UI restricts template import to REST datasources only","Validate datasource IDs come from the current app's REST resources"],"tags":["rest-template","datasource","rest"],"backgroundTag":"incompatible-resource-type","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}