jaegertracing/jaeger · error

UI config file must define function UIConfig(): %v

Error message

UI config file must define function UIConfig(): %v

What it means

A UI config file with a .js extension must define a JavaScript function named UIConfig(), verified by regex `function\s+UIConfig(\s)?\(\s?\)(\s)?{`. If the trimmed file content does not match, loadUIConfig rejects it because the handler cannot inject a config the UI can call. Note this rejects arrow functions and minified forms like function UIConfig(){...} only if the regex fails (it actually matches that), but rejects `const UIConfig = () => ({...})`.

Source

Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/static_handler.go:236

	ext := filepath.Ext(uiConfig)
	switch strings.ToLower(ext) {
	case ".json":
		var c map[string]any

		if err := json.Unmarshal(bytesConfig, &c); err != nil {
			return nil, fmt.Errorf("cannot parse UI config file %v: %w", uiConfig, err)
		}
		r, _ = json.Marshal(c)

		return &loadedConfig{
			regexp: configPattern,
			config: append([]byte("JAEGER_CONFIG = "), append(r, byte(';'))...),
		}, nil
	case ".js":
		r = bytes.TrimSpace(bytesConfig)
		re := regexp.MustCompile(`function\s+UIConfig(\s)?\(\s?\)(\s)?{`)
		if !re.Match(r) {
			return nil, fmt.Errorf("UI config file must define function UIConfig(): %v", uiConfig)
		}

		return &loadedConfig{
			regexp: configJsPattern,
			config: r,
		}, nil
	default:
		return nil, fmt.Errorf("unrecognized UI config file format, expecting .js or .json file: %v", uiConfig)
	}
}

func (h *staticAssetsHandler) loggingHandler(handler http.Handler) http.Handler {
	if !h.logAccess {
		return handler
	}
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		h.logger.Info("serving static asset", zap.Stringer("url", r.URL))
		handler.ServeHTTP(w, r)

View on GitHub (pinned to 806f444784)

Solutions

  1. Define the config as a plain `function UIConfig() { return {...}; }` at the top level of the file.
  2. Remove `export` keywords and arrow-function syntax — Jaeger expects the classic function declaration.
  3. Verify the file extension is .js and content is plain browser-side JS, not a module or bundle.
  4. Check the file is non-empty and wasn't replaced by an HTML error page.

Example fix

// before (ui-config.js)
export const UIConfig = () => ({ menu: [] });
// after
function UIConfig() {
  return { menu: [] };
}
Defensive patterns

Strategy: validation

Validate before calling

re := regexp.MustCompile(`function\s+UIConfig(\s)?\(\s?\)(\s)?{`)
if !re.Match(bytes.TrimSpace(jsBytes)) {
    return fmt.Errorf("%s must define `function UIConfig() {`", path)
}

Prevention

When it happens

Trigger: loadUIConfig with a .js file where bytes.TrimSpace(bytesConfig) does not match the UIConfig function regex: file defines UIConfig as a const arrow function, uses `export function UIConfig() {`, defines a differently named function, or the file is empty/HTML.

Common situations: Copying an ES-module style config (export const UIConfig = ...) from a modern JS project; renaming the function; pointing ui-config at a random .js bundle instead of a config; whitespace/encoding oddities from Windows line endings in unusual positions.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/2d7701f2487a0e5d. Report an issue: GitHub.