{"record":{"id":"856885b404b0d2f4","repo":"MagicMirrorOrg/MagicMirror","slug":"setcallbacks-must-be-called-before-initialize","errorCode":null,"errorMessage":"setCallbacks() must be called before initialize()","messagePattern":"setCallbacks\\(\\) must be called before initialize\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"defaultmodules/weather/providers/openweathermap.js","lineNumber":34,"sourceCode":"\t\t\tlocation: false,\n\t\t\tlat: 0,\n\t\t\tlon: 0,\n\t\t\tapiKey: \"\",\n\t\t\ttype: \"current\",\n\t\t\tupdateInterval: 10 * 60 * 1000,\n\t\t\t...config\n\t\t};\n\n\t\tthis.fetcher = null;\n\t\tthis.onDataCallback = null;\n\t\tthis.onErrorCallback = null;\n\t\tthis.locationName = null;\n\t}\n\n\tinitialize () {\n\t\t// Validate callbacks exist\n\t\tif (typeof this.onErrorCallback !== \"function\") {\n\t\t\tthrow new Error(\"setCallbacks() must be called before initialize()\");\n\t\t}\n\n\t\tif (!this.config.apiKey) {\n\t\t\tLog.error(\"[openweathermap] API key is required\");\n\t\t\tthis.onErrorCallback({\n\t\t\t\tmessage: \"API key is required\",\n\t\t\t\ttranslationKey: \"MODULE_ERROR_UNSPECIFIED\"\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#initializeFetcher();\n\t}\n\n\tsetCallbacks (onData, onError) {\n\t\tthis.onDataCallback = onData;\n\t\tthis.onErrorCallback = onError;\n\t}","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/MagicMirrorOrg/MagicMirror/blob/4b4a59534f7da01e4030e46029fe9dd649a7675e/defaultmodules/weather/providers/openweathermap.js#L16-L52","documentation":"openweathermap's initialize() requires callbacks to be registered first via setCallbacks(); it throws synchronously if onErrorCallback is not a function. This ensures the provider always has a channel to report later async failures (API key problems, fetch errors) instead of crashing unhandled.","triggerScenarios":"Calling initialize() before setCallbacks(), or calling setCallbacks() with missing/incorrect arguments so onErrorCallback stays undefined.","commonSituations":"Refactored init order after upgrade; forgetting the callbacks step in new wiring; passing setCallbacks(onData) with only one argument.","solutions":["Call provider.setCallbacks(onDataCallback, onErrorCallback) before initialize()","Ensure both callbacks are functions (not undefined/null)","Reorder your bootstrap code so callback registration precedes initialize()"],"exampleFix":"// before\nprovider.initialize(config);\nprovider.setCallbacks(onData, onError);\n// after\nprovider.setCallbacks(onData, onError);\nprovider.initialize(config);","handlingStrategy":"try-catch","validationCode":"if (typeof provider.onErrorCallback !== \"function\") {\n  throw new Error(\"Call setCallbacks(onData, onError) before initialize()\");\n}\nprovider.initialize(config);","typeGuard":"const isCallbackFn = (f) => typeof f === \"function\";","tryCatchPattern":"try {\n  provider.initialize(config);\n} catch (err) {\n  if (err.message.includes(\"setCallbacks() must be called before initialize()\")) {\n    provider.setCallbacks(onData, onError);\n    provider.initialize(config); // retry once with correct order\n  } else throw err;\n}","preventionTips":["Always register callbacks as the first provider call","Wire setCallbacks(onDataCallback, onErrorCallback) with both arguments","Enforce init order in a shared factory/bootstrap helper","Code-review any upgrade that changes provider bootstrap"],"tags":["config","lifecycle","openweathermap"],"backgroundTag":"method-called-out-of-order","analyzedSha":"4b4a59534f7da01e4030e46029fe9dd649a7675e","analyzedAt":"2026-08-31T21:49:42.591Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}