Skip to content

Custom theme causes panic due to missing markdown properties #488

Closed

Description

@arobida

Bug Report

Summary

Custom themes that don't include all required markdown properties cause a nil pointer dereference panic during theme initialization, making the application completely unusable.

Error Details

Caught panic:
runtime error: invalid memory address or nil pointer dereference
...
github.com/lucasb-eyer/go-colorful.MakeColor({0x0?, 0x0?})
        /home/runner/go/pkg/mod/github.com/lucasb-eyer/go-colorful@v1.2.0/colors.go:26 +0x20
github.com/sst/opencode/internal/styles.AdaptiveColorToString({{0x0?, 0x0?}, {0x0?, 0x0?}})
        /home/runner/work/opencode/opencode/packages/tui/internal/styles/markdown.go:317 +0x64
github.com/sst/opencode/internal/styles.generateMarkdownStyleConfig({{_, *}, {*, _}})
        /home/runner/work/opencode/opencode/packages/tui/internal/styles/markdown.go:41 +0x94

Root Cause

The crash occurs when generateMarkdownStyleConfig tries to create colors from theme properties that don't exist. When markdown properties are missing from a custom theme, the program attempts to create colors from nil/empty values, causing the panic in MakeColor.

Steps to Reproduce

  1. Create a custom theme JSON file missing markdown properties (e.g., markdownText, markdownHeading, etc.)
  2. Place it in a theme directory (e.g., ~/.config/opencode/themes/)
  3. Launch opencode with this theme
  4. Application immediately panics and crashes

Example Problematic Theme

Any theme that follows the documented schema but omits markdown properties will trigger this:

{
    "$schema": "https://opencode.ai/theme.json",
    "defs": {
        "black": "#21222c",
        "red": "#f9515d"
    },
    "theme": {
        "primary": { "light": "red", "dark": "red" },
        "background": { "light": "black", "dark": "black" }
        // Missing markdown properties causes panic
    }
}

Expected Behavior

  • Application should provide sensible fallbacks for missing theme properties
  • OR clearly document which properties are required vs optional
  • OR gracefully handle missing properties without panicking

Actual Behavior

Application panics with nil pointer dereference, making it completely unusable.

Workaround

Add all required markdown properties to the theme:

"markdownText": { "light": "black", "dark": "white" },
"markdownHeading": { "light": "blue", "dark": "blue" },
"markdownLink": { "light": "cyan", "dark": "cyan" },
"markdownLinkText": { "light": "cyan", "dark": "cyan" },
"markdownCode": { "light": "green", "dark": "green" },
"markdownBlockQuote": { "light": "brightBlack", "dark": "brightBlack" },
"markdownEmph": { "light": "yellow", "dark": "yellow" },
"markdownStrong": { "light": "red", "dark": "red" },
"markdownHorizontalRule": { "light": "brightBlack", "dark": "brightBlack" },
"markdownListItem": { "light": "cyan", "dark": "cyan" },
"markdownListEnumeration": { "light": "cyan", "dark": "cyan" },
"markdownImage": { "light": "blue", "dark": "blue" },
"markdownImageText": { "light": "cyan", "dark": "cyan" },
"markdownCodeBlock": { "light": "white", "dark": "white" },
"diffHunkHeader": { "light": "brightBlack", "dark": "brightBlack" }

Environment

  • opencode version: Latest (occurs across versions)
  • OS: Multiple (reproduced on different systems)
  • Theme: Custom theme following documented schema

Suggested Fixes

  1. Add defensive programming: Check for nil/missing properties before calling MakeColor
  2. Provide fallbacks: Use default colors when theme properties are missing
  3. Improve documentation: Clearly specify which theme properties are required
  4. Schema validation: Validate themes on load and provide helpful error messages

This is a significant usability issue as it makes custom themes completely unusable unless users know the undocumented requirement for all markdown properties.

Activity

  1. adamdotdevin commented on Jun 28, 2025

    @adamdotdevin
    Member

    yeah, i had to move on but themes have an end state i really want to get to. right now you have to provide every value, but you can at least use aliases to simplify this.

    the end state id love to see (and if someone has time and wants to take this on please do let me know) is basically you could define as little as the primary color only, and then it does color wheel calculations to come up with defaults for everything else. not that that's a very useful use case, but my point is that we can calculate everything off of primary color. we already do calcs for the different background shades in the system theme, same idea. so, we calculate fallback colors for any that are missing, and in some cases it's just reusing colors sensibly (ie, all of the syntax highlighting colors can derive from the other colors defined further "up").

  2. adamdotdevin commented on Jun 28, 2025

    @adamdotdevin
    Member

    if you want to make a custom theme today probably easiest to copy the example in the docs and just change colors in it

  3. arobida commented on Jun 28, 2025

    @arobida
    Author

    I understand and honestly the new system theme kind of kills the need for a custom theme if you just want it to match your terminal. Warp terminal has some way of generating custom themes to match their format but I don't know too much about it.

  4. rekram1-node commented on Dec 28, 2025

    @rekram1-node
    Contributor

    [automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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