{"record":{"id":"955314f0aa4e346a","repo":"flowable/flowable-engine","slug":"model-with-id-modelid-does-not-have-extra-sou","errorCode":null,"errorMessage":"Model with id '${modelId}' does not have extra source available.","messagePattern":"Model with id '(.+?)' does not have extra source available\\.","errorType":"http","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ModelSourceExtraResource.java","lineNumber":59,"sourceCode":"/**\n * @author Frederik Heremans\n */\n@RestController\n@Api(tags = { \"Models\" }, authorizations = { @Authorization(value = \"basicAuth\") })\npublic class ModelSourceExtraResource extends BaseModelSourceResource {\n\n    @ApiOperation(value = \"Get the extra editor source for a model\", tags = { \"Models\" }, nickname = \"getExtraEditorSource\",\n            notes = \"Response body contains the model’s raw editor source. The response’s content-type is set to application/octet-stream, regardless of the content of the source.\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the model was found and source is returned.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested model was not found.\")\n    })\n    @GetMapping(\"/repository/models/{modelId}/source-extra\")\n    public byte[] getModelBytes(@ApiParam(name = \"modelId\") @PathVariable String modelId, HttpServletResponse response) {\n        Model model = getModelFromRequest(modelId);\n        byte[] editorSource = repositoryService.getModelEditorSourceExtra(model.getId());\n        if (editorSource == null) {\n            throw new FlowableObjectNotFoundException(\"Model with id '\" + modelId + \"' does not have extra source available.\", String.class);\n        }\n        response.setContentType(\"application/octet-stream\");\n        return editorSource;\n    }\n\n    @ApiOperation(value = \"Set the extra editor source for a model\", tags = { \"Models\" }, nickname = \"setExtraEditorSource\", consumes = \"multipart/form-data\",\n            notes = \"Response body contains the model’s raw editor source. The response’s content-type is set to application/octet-stream, regardless of the content of the source.\",\n            code = 204)\n    @ApiImplicitParams({\n            @ApiImplicitParam(name = \"file\", dataType = \"file\", paramType = \"form\", required = true)\n    })\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the model was found and the extra source has been updated.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested model was not found.\")\n    })\n    @PutMapping(value = \"/repository/models/{modelId}/source-extra\", consumes = \"multipart/form-data\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void setModelSource(@ApiParam(name = \"modelId\") @PathVariable String modelId, HttpServletRequest request) {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ModelSourceExtraResource.java#L41-L77","documentation":"Thrown by the Flowable REST API when GET /repository/models/{modelId}/source-extra is called for a model that exists but has no extra editor source bytes stored. Flowable stores the 'extra' editor source separately from the model itself; repositoryService.getModelEditorSourceExtra returns null and the resource raises FlowableObjectNotFoundException.","triggerScenarios":"GET /repository/models/{modelId}/source-extra on a model that was created or saved without ever calling addModelEditorSourceExtra (e.g. a model created via the REST API or designer that only has base source or no source at all).","commonSituations":"Deploying models programmatically without setting extra source; copying a model and forgetting to copy the extra source; clients assuming source-extra exists whenever source exists; upgrading Flowable where legacy models were imported without extra source.","solutions":["Verify the model id is correct and that the intended model actually has extra source (GET /repository/models/{modelId} and check the model in ACT_RE_MODEL)","Set the extra source first via PUT /repository/models/{modelId}/source-extra with a multipart file, then re-fetch","If the extra source is genuinely absent, handle 404 on the client instead of treating it as fatal","If the model should have extra source but does not, re-save it from the source of truth (designer/import)"],"exampleFix":"// before\ncurl -X GET http://localhost:8080/flowable-rest/repository/models/myModelId/source-extra\n// after\ncurl -X PUT -F 'file=@extra-source.xml' http://localhost:8080/flowable-rest/repository/models/myModelId/source-extra\ncurl -X GET http://localhost:8080/flowable-rest/repository/models/myModelId/source-extra","handlingStrategy":"try-catch","validationCode":"Model m = repositoryService.createModelQuery().modelId(modelId).singleResult();\nboolean hasExtra = m != null && repositoryService.getModelEditorSourceExtra(m.getId()) != null;\nif (!hasExtra) throw new IllegalStateException(\"model has no extra source\");","typeGuard":null,"tryCatchPattern":"try { byte[] b = getModelBytes(modelId); } catch (FlowableObjectNotFoundException e) { /* model exists but no extra source; use default */ }","preventionTips":["Always call addModelEditorSourceExtra when saving models intended to expose extra source","Check GET /repository/models/{modelId} before fetching source endpoints","Treat source/source-extra as optional in client code"],"tags":["flowable","rest","resource-not-found","model"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}