{"record":{"id":"b84b6fa0525a4d06","repo":"zaproxy/zaproxy","slug":"failed-to-read-a-callback-entry-required-prefix-i","errorCode":null,"errorMessage":"Failed to read a callback entry, required prefix is empty.","messagePattern":"Failed to read a callback entry, required prefix is empty\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"zap/src/main/java/org/zaproxy/zap/extension/api/OptionsParamApi.java","lineNumber":430,"sourceCode":"        this.confirmRemovePermittedAddress = confirmRemove;\n        getConfig().setProperty(CONFIRM_REMOVE_ADDRESS, confirmRemovePermittedAddress);\n    }\n\n    private void loadPersistentCallBacks() {\n        List<HierarchicalConfiguration> fields =\n                ((HierarchicalConfiguration) getConfig()).configurationsAt(CALLBACK_KEY);\n\n        persistentCallBacks = new HashMap<>(fields.size());\n\n        for (HierarchicalConfiguration sub : fields) {\n            String cbUrl = sub.getString(CALLBACK_URL_KEY, \"\");\n            if (cbUrl.isEmpty()) {\n                LOGGER.warn(\"Failed to read a callback entry, required url is empty.\");\n                continue;\n            }\n            String cbPrefix = sub.getString(CALLBACK_PREFIX_KEY, null);\n            if (cbPrefix == null) {\n                LOGGER.warn(\"Failed to read a callback entry, required prefix is empty.\");\n                continue;\n            }\n            persistentCallBacks.put(cbUrl, cbPrefix);\n        }\n    }\n\n    private void savePersistentCallBacks() {\n        ((HierarchicalConfiguration) getConfig()).clearTree(CALLBACK_KEY);\n\n        int i = 0;\n        for (Entry<String, String> entry : persistentCallBacks.entrySet()) {\n            String elementBaseKey = CALLBACK_KEY + \"(\" + i + \").\";\n            getConfig().setProperty(elementBaseKey + CALLBACK_URL_KEY, entry.getKey());\n            getConfig().setProperty(elementBaseKey + CALLBACK_PREFIX_KEY, entry.getValue());\n            i++;\n        }\n        try {\n            getConfig().save();","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/zaproxy/zaproxy/blob/9d1970a436b1b189bfb588fc88864c80d9baf6a5/zap/src/main/java/org/zaproxy/zap/extension/api/OptionsParamApi.java#L412-L448","documentation":"OptionsParamApi.loadPersistentCallBacks requires both a URL and a prefix for each persistent callback entry. When the CALLBACK_PREFIX_KEY is absent or null for an entry that has a valid URL, the entry is skipped with this warning.","triggerScenarios":"A config.xml <callback> entry contains a URL but no <prefix> child (or it is literally stored as null) — typically from manual edits or an incomplete save by the component registering callbacks.","commonSituations":"Hand-edited config files; older config formats migrated to a version that introduced required prefixes; scripts writing callback entries programmatically.","solutions":["Add the missing <prefix> value to the callback entry in the config file","Remove the incomplete entry and re-register the persistent callback through its owning extension","Inspect the extension that created the entry and ensure it persists both url and prefix"],"exampleFix":"// before (config.xml)\n<callback><url>https://example.com/cb</url></callback>\n// after\n<callback><url>https://example.com/cb</url><prefix>zap</prefix></callback>","handlingStrategy":"validation","validationCode":"// before deploying config.xml\n// fail if any <callback> lacks a non-empty <prefix>\n// xmlstarlet sel -t -v \"count(//callback[url and not(string(prefix))])\" config.xml -> must be 0","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Always persist url AND prefix for persistent callbacks","Let the owning extension write callback entries, not manual edits","Validate config.xml against the expected OptionsParamApi schema","Review ZAP upgrade notes for config format changes to callback entries"],"tags":["java","configuration","zap"],"backgroundTag":"missing-config-value","analyzedSha":"9d1970a436b1b189bfb588fc88864c80d9baf6a5","analyzedAt":"2026-09-05T19:26:59.356Z","contentChangedAt":"2026-09-05T19:26:59.356Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}