Skip to content

Building Documentation fails if mkdocs-static-i18n plugin is used #312

@ba-lindner

Description

@ba-lindner

When trying to build documentation for techdocs that uses the mkdocs-static-i18n plugin, the build fails with KeyError: 'techdocs-core' in this line:

del config["plugins"]["techdocs-core"]

Log
info: Step 1 of 3: Preparing docs for entity component:default/artist-web {"timestamp":"2025-11-18T15:00:59.499Z"}
info: Prepare step completed for entity component:default/artist-web, stored at /tmp/backstage-qE5Pg8 {"timestamp":"2025-11-18T15:01:00.289Z"}
info: Step 2 of 3: Generating docs for entity component:default/artist-web {"timestamp":"2025-11-18T15:01:00.289Z"}
info: Set {"repo_url":"[...]","edit_uri":"[...]"}. You can disable this feature by manually setting 'repo_url' or 'edit_uri' according to the MkDocs documentation at https://www.mkdocs.org/user-guide/configuration/#repo_url {"timestamp":"2025-11-18T15:01:00.295Z"}
DEBUG   -  Loading configuration file: /tmp/backstage-qE5Pg8/mkdocs.yml
DEBUG   -  Loaded theme configuration for 'mkdocs' from '/opt/venv/lib/python3.11/site-packages/mkdocs/themes/mkdocs/mkdocs_theme.yml': {'static_templates': ['404.html'], 'locale': 'en', 'include_search_page': False, 'search_index_only': False, 'highlightjs': True, 'hljs_languages': [], 'hljs_style': 'github', 'hljs_style_dark': 'github-dark', 'navigation_depth': 2, 'nav_style': 'primary', 'color_mode': 'light', 'user_color_mode_toggle': False, 'analytics': {'gtag': None}, 'shortcuts': {'help': 191, 'next': 78, 'previous': 80, 'search': 83}}
DEBUG   -  Config value 'config_file_path' = '/tmp/backstage-qE5Pg8/mkdocs.yml'
DEBUG   -  Config value 'site_name' = 'artist-web-docs'
DEBUG   -  Config value 'nav' = [{'Getting Started': 'index.md'}]
DEBUG   -  Config value 'pages' = None
DEBUG   -  Config value 'exclude_docs' = None
DEBUG   -  Config value 'draft_docs' = None
DEBUG   -  Config value 'not_in_nav' = None
DEBUG   -  Config value 'site_url' = None
DEBUG   -  Config value 'site_description' = 'Example Documentation'
DEBUG   -  Config value 'site_author' = None
DEBUG   -  Config value 'theme' = Theme(name='mkdocs', dirs=['/opt/venv/lib/python3.11/site-packages/mkdocs/themes/mkdocs', '/opt/venv/lib/python3.11/site-packages/mkdocs/templates'], static_templates={'sitemap.xml', '404.html'}, name='mkdocs', locale=Locale('en'), include_search_page=False, search_index_only=False, highlightjs=True, hljs_languages=[], hljs_style='github', hljs_style_dark='github-dark', navigation_depth=2, nav_style='primary', color_mode='light', user_color_mode_toggle=False, analytics={'gtag': None}, shortcuts={'help': 191, 'next': 78, 'previous': 80, 'search': 83})
DEBUG   -  Config value 'docs_dir' = '/tmp/backstage-qE5Pg8/docs'
DEBUG   -  Config value 'site_dir' = '/tmp/techdocs-tmp-R2gDrg'
DEBUG   -  Config value 'copyright' = None
DEBUG   -  Config value 'google_analytics' = None
DEBUG   -  Config value 'dev_addr' = _IpAddressValue(host='127.0.0.1', port=8000)
DEBUG   -  Config value 'use_directory_urls' = True
DEBUG   -  Config value 'repo_url' = '[...]'
DEBUG   -  Config value 'repo_name' = 'Ibkgit02'
DEBUG   -  Config value 'edit_uri_template' = None
DEBUG   -  Config value 'edit_uri' = '[...]'
DEBUG   -  Config value 'extra_css' = []
DEBUG   -  Config value 'extra_javascript' = []
DEBUG   -  Config value 'extra_templates' = []
DEBUG   -  Config value 'markdown_extensions' = ['toc', 'tables', 'fenced_code']
DEBUG   -  Config value 'mdx_configs' = {}
DEBUG   -  Config value 'strict' = False
DEBUG   -  Config value 'remote_branch' = 'gh-pages'
DEBUG   -  Config value 'remote_name' = 'origin'
DEBUG   -  Config value 'extra' = {}
DEBUG   -  Config value 'plugins' = {'techdocs-core': <techdocs_core.core.TechDocsCore object at 0x7f05c65b7f90>, 'i18n': <mkdocs_static_i18n.plugin.I18n object at 0x7f05c600bc10>}
DEBUG   -  Config value 'hooks' = {}
DEBUG   -  Config value 'watch' = []
DEBUG   -  Config value 'validation' = {'nav': {'omitted_files': 20, 'not_found': 30, 'absolute_links': 20}, 'links': {'not_found': 30, 'absolute_links': 20, 'unrecognized_links': 20, 'anchors': 20}}
DEBUG   -  Running `config` event from plugin 'techdocs-core'
DEBUG   -  Loaded theme configuration for 'material' from '/opt/venv/lib/python3.11/site-packages/material/templates/mkdocs_theme.yml': {'language': 'en', 'direction': None, 'features': [], 'font': {'text': 'Roboto', 'code': 'Roboto Mono'}, 'icon': None, 'favicon': 'assets/images/favicon.png', 'static_templates': ['404.html']}
DEBUG   -  Running `config` event from plugin 'search'
DEBUG   -  Running `config` event from plugin 'monorepo'
DEBUG   -  Running `config` event from plugin 'i18n'
INFO    -  mkdocs_static_i18n: Building 'en' documentation to directory: /tmp/techdocs-tmp-R2gDrg
INFO    -  mkdocs_static_i18n: Adding 'de' to the 'search' plugin 'lang' option
DEBUG   -  Running `pre_build` event from plugin 'search'
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: /tmp/techdocs-tmp-R2gDrg
DEBUG   -  Looking for translations for locale 'en'
DEBUG   -  No translations found here: '/opt/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/locales'
DEBUG   -  No translations found here: '/tmp/tmpcvz0zuhb/locales'
DEBUG   -  No translations found here: '/opt/venv/lib/python3.11/site-packages/mkdocs/templates/locales'
DEBUG   -  No translations found here: '/opt/venv/lib/python3.11/site-packages/material/templates/locales'
DEBUG   -  No translations found here: '/opt/venv/lib/python3.11/site-packages/mkdocs_static_i18n/custom_i18n_sitemap/locales'
DEBUG   -  Running `files` event from plugin 'i18n'
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.de.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='/tmp/techdocs-tmp-R2gDrg', use_directory_urls=True, dest_uri='index.de/index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.de.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.de/index.html', use_directory_urls=True, dest_uri='index.html', inclusion=InclusionLevel.INCLUDED) from locale de
DEBUG   -  mkdocs_static_i18n: Ignore de de File('index.de.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.de/index.html', use_directory_urls=True, dest_uri='index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.en.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='/tmp/techdocs-tmp-R2gDrg', use_directory_urls=True, dest_uri='index.en/index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.en.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.en/index.html', use_directory_urls=True, dest_uri='index.html', inclusion=InclusionLevel.INCLUDED) from locale en
DEBUG   -  mkdocs_static_i18n: Use en en File('index.en.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.en/index.html', use_directory_urls=True, dest_uri='index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: Selected en en File('index.en.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.en/index.html', use_directory_urls=True, dest_uri='index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.de.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='/tmp/techdocs-tmp-R2gDrg', use_directory_urls=True, dest_uri='index.de/index.html', inclusion=InclusionLevel.INCLUDED)
DEBUG   -  mkdocs_static_i18n: reconfigure File('index.de.md', src_dir='/tmp/docs_ocs44h_h', dest_dir='index.de/index.html', use_directory_urls=True, dest_uri='de/index.html', inclusion=InclusionLevel.INCLUDED) from locale de
DEBUG   -  Running `nav` event from plugin 'i18n'
DEBUG   -  Reading markdown pages.
DEBUG   -  Reading: index.en.md
DEBUG   -  Running `pre_page` event from plugin 'monorepo'
DEBUG   -  Running `page_markdown` event from plugin 'i18n'
DEBUG   -  Running `env` event from plugin 'i18n'
DEBUG   -  Copying static assets.
DEBUG   -  Copying media file: 'assets/images/favicon.png'
DEBUG   -  Copying media file: 'assets/javascripts/bundle.92b07e13.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/bundle.92b07e13.min.js.map'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/min/lunr.ar.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/min/lunr.da.min.js'
[.. snip a bunch of identical lines ..]
DEBUG   -  Copying media file: 'assets/javascripts/lunr/min/lunr.tr.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/min/lunr.vi.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/min/lunr.zh.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/tinyseg.js'
DEBUG   -  Copying media file: 'assets/javascripts/lunr/wordcut.js'
DEBUG   -  Copying media file: 'assets/javascripts/workers/search.973d3a69.min.js'
DEBUG   -  Copying media file: 'assets/javascripts/workers/search.973d3a69.min.js.map'
DEBUG   -  Copying media file: 'assets/stylesheets/main.7e37652d.min.css'
DEBUG   -  Copying media file: 'assets/stylesheets/main.7e37652d.min.css.map'
DEBUG   -  Copying media file: 'assets/stylesheets/palette.06af60db.min.css'
DEBUG   -  Copying media file: 'assets/stylesheets/palette.06af60db.min.css.map'
DEBUG   -  Copying media file: 'search/lunr.js'
DEBUG   -  Copying media file: 'search/main.js'
DEBUG   -  Copying media file: 'search/worker.js'
DEBUG   -  Building theme template: techdocs_metadata.json
DEBUG   -  Running `template_context` event from plugin 'i18n'
DEBUG   -  Building theme template: sitemap.xml
DEBUG   -  Running `template_context` event from plugin 'i18n'
DEBUG   -  Gzipping template: sitemap.xml
DEBUG   -  Building theme template: 404.html
DEBUG   -  Running `template_context` event from plugin 'i18n'
DEBUG   -  Building markdown pages.
DEBUG   -  Building page index.en.md
DEBUG   -  Running `page_context` event from plugin 'i18n'
DEBUG   -  Running `page_context` event from plugin 'search'
DEBUG   -  Running `post_page` event from plugin 'i18n'
DEBUG   -  Running `post_build` event from plugin 'search'
DEBUG   -  Running `post_build` event from plugin 'i18n'
DEBUG   -  Running `config` event from plugin 'techdocs-core'
Traceback (most recent call last):
  File "/opt/venv/bin/mkdocs", line 8, in <module>
sys.exit(cli())
^^^^^
  File "/opt/venv/lib/python3.11/site-packages/click/core.py", line 1442, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/click/core.py", line 1363, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/click/core.py", line 1830, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/click/core.py", line 1226, in invoke
return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/click/core.py", line 794, in invoke
return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/__main__.py", line 288, in build_command
    build.build(cfg, dirty=not clean)
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/commands/build.py", line 347, in build
config.plugins.on_post_build(config=config)
File "/opt/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 602, in on_post_build
return self.run_event('post_build', config=config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 568, in run_event
result = method(**kwargs)
             ^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.11/site-packages/mkdocs_static_i18n/plugin.py", line 253, in on_post_build
build(config, dirty=dirty)
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/commands/build.py", line 265, in build
config = config.plugins.on_config(config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 587, in on_config
    return self.run_event('config', config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 566, in run_event
    result = method(item, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/venv/lib/python3.11/site-packages/techdocs_core/core.py", line 88, in on_config
del config["plugins"]["techdocs-core"]
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'techdocs-core'
error: Failed to build the docs page for entity component:default/artist-web: Failed to generate docs from /tmp/backstage-ljxbvp into /tmp/techdocs-tmp-wlomS5; caused by unknown error 'Command mkdocs failed, exit code: 1' {"timestamp":"2025-11-18T14:23:42.613Z"}

I assume that the error occurs because mkdocs-static-i18n causes the config event to be raised once per language instead of exactly once (the line Running `config` event from plugin 'techdocs-core' occurs twice in the log: the first line after listing all config values and the last line before the traceback). This way, in the second round, config["plugins"]["techdocs-core"] is already deleted and cannot be deleted again.

A solution I found was to add the following snippet to the beginning of the on_config function in core.py:

if "techdocs-core" not in config["plugins"]:
    return config

Minimal Example to reproduce

  • mkdocs.yml:
    site_name: artist-web-docs
    site_description: Example Documentation
    plugins:
      - techdocs-core
      - i18n:
          docs_structure: suffix
          languages:
          - locale: en
            default: true
            name: English
          - locale: de
            name: Deutsch
    nav:
      - Getting Started: index.md
  • Add some placeholder content to docs/index.en.md and docs/index.de.md
  • Install mkdocs-static-i18n with pip3 install mkdocs-static-i18n
  • Try building docs with mkdocs build

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions