{"record":{"id":"bcc195cd06a33abd","repo":"codex-team/editor.js","slug":"can-t-start-without-tools","errorCode":null,"errorMessage":"Can't start without tools","messagePattern":"Can't start without tools","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/components/modules/tools.ts","lineNumber":117,"sourceCode":"  public get internal(): ToolsCollection {\n    return this.available.internalTools;\n  }\n\n  /**\n   * Creates instances via passed or default configuration\n   *\n   * @returns {Promise<void>}\n   */\n  public async prepare(): Promise<void> {\n    this.validateTools();\n\n    /**\n     * Assign internal tools\n     */\n    this.config.tools = _.deepMerge({}, this.internalTools, this.config.tools);\n\n    if (!Object.prototype.hasOwnProperty.call(this.config, 'tools') || Object.keys(this.config.tools).length === 0) {\n      throw Error('Can\\'t start without tools');\n    }\n\n    const config = this.prepareConfig();\n\n    this.factory = new ToolsFactory(config, this.config, this.Editor.API);\n\n    /**\n     * getting classes that has prepare method\n     */\n    const sequenceData = this.getListOfPrepareFunctions(config);\n\n    /**\n     * if sequence data contains nothing then resolve current chain and run other module prepare\n     */\n    if (sequenceData.length === 0) {\n      return Promise.resolve();\n    }\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/codex-team/editor.js/blob/5f45dabbe5690b7033b2f9047d3985add5045fdd/src/components/modules/tools.ts#L99-L135","documentation":"Editor.js throws this during Editor initialization (prepare) when, after merging internal tools with user-provided config.tools, the resulting tools object is empty. The library refuses to start because an editor with no tools would be unusable. It also fires when the tools key is missing entirely from the config object.","triggerScenarios":"Calling new EditorJS({...}) without a tools property, or passing tools: {} (empty object). It can also occur if tools is passed as undefined/null or a non-plain object whose keys don't survive Object.keys(), since the merge of internalTools with user tools yields nothing usable.","commonSituations":"Most commonly a developer copies a minimal example and forgets the tools block, or builds config dynamically (e.g. tools: loadedTools where loadedTools is an empty object before an async fetch resolves). Also happens when config is spread from another object that omits tools, or after upgrading from examples that assumed default tools exist.","solutions":["Add a non-empty tools object to the Editor.js config: tools: { paragraph: Paragraph } (import @editorjs/paragraph or another tool).","If tools are loaded asynchronously, await them before constructing new EditorJS(...); construct the editor only after tools resolve.","Debug-log Object.keys(config.tools || {}) right before initialization to confirm the object is populated.","Never pass tools: {} or undefined; at minimum register the Paragraph tool, which Editor.js expects for block editing."],"exampleFix":"// before\nconst editor = new EditorJS({ holder: 'editor-js' });\n\n// after\nimport Paragraph from '@editorjs/paragraph';\nconst editor = new EditorJS({\n  holder: 'editor-js',\n  tools: {\n    paragraph: Paragraph\n  }\n});","handlingStrategy":"validation","validationCode":"import Paragraph from '@editorjs/paragraph';\n\nfunction assertToolsReady(config) {\n  if (!config.tools || Object.keys(config.tools).length === 0) {\n    throw new Error('Editor.js config.tools is empty — register at least one tool (e.g. paragraph) before init.');\n  }\n}\n\n// before new EditorJS(...):\nassertToolsReady(config);","typeGuard":"function hasValidTools(config) {\n  return Object.prototype.hasOwnProperty.call(config, 'tools')\n    && config.tools !== null\n    && typeof config.tools === 'object'\n    && Object.keys(config.tools).length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always include at least the Paragraph tool in every Editor.js config.","When tools load asynchronously, await them before constructing the editor.","Type your config as { tools: Record<string, unknown> } and fail fast on empty objects in dev builds."],"tags":["editorjs","configuration","initialization","tools"],"backgroundTag":"missing-required-config-option","analyzedSha":"5f45dabbe5690b7033b2f9047d3985add5045fdd","analyzedAt":"2026-08-27T22:50:23.124Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}