sqshq/sampler · critical

Failed to find component type

Error message

Failed to find component type %v with title %v

What it means

Config.Update locates the component config matching a type and title via findComponent; if no component of the given type has the given title, it panics with "Failed to find component type %v with title %v". This guards the invariant that runtime updates must reference an existing configured component — a missing match means the update cannot be applied safely.

Solutions

  1. Verify the component's title in the YAML matches exactly (including case and spaces) what the update request sends
  2. Re-read/reload the config before updating if components were recently added or removed
  3. Replace the panic with an error return: change findComponent to return (*ComponentConfig, error) and have Update propagate it
  4. Add a pre-check in the caller that the component exists before issuing an update

Example fix

// before
panic(fmt.Sprintf(
    "Failed to find component type %v with title %v", componentType, componentTitle))
// after
return nil, fmt.Errorf("failed to find component type %v with title %v", componentType, componentTitle)
Defensive patterns

Strategy: validation

Validate before calling

func componentExists(cfg *config.Config, ctype, title string) bool {
    // iterate configured components and compare Title/type before Update
    return findIndex(cfg, ctype, title) >= 0
}

Try / catch

func updateSafe(cfg *config.Config, ctype, title string, data []byte) (err error) {
    defer func() { if r := recover(); r != nil { err = fmt.Errorf("update failed: %v", r) } }()
    cfg.Update(ctype, title, data)
    return nil
}

Prevention

When it happens

Trigger: Calling Update (e.g. from the web/API layer) with a componentType/title pair that does not exist in the loaded Config — wrong title casing, component removed from YAML, or mismatched type (textbox vs run-chart vs gauges...).

Common situations: Web UI or API client sending a stale title after the user renamed/removed the component in the YAML; programmatic updates constructing titles by string concatenation; case-sensitivity mismatches between config and request.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of sqshq/sampler@9bc7ba732d (2026-09-06). Data as JSON: /api/errors/4b0d578c16fe74c1. Report an issue: GitHub.

Appendix: source

Thrown at config/config.go:98

			if component.Title == componentTitle {
				return &c.SparkLines[i].ComponentConfig
			}
		}
	case TypeAsciiBox:
		for i, component := range c.AsciiBoxes {
			if component.Title == componentTitle {
				return &c.AsciiBoxes[i].ComponentConfig
			}
		}
	case TypeTextBox:
		for i, component := range c.TextBoxes {
			if component.Title == componentTitle {
				return &c.TextBoxes[i].ComponentConfig
			}
		}
	}

	panic(fmt.Sprintf(
		"Failed to find component type %v with title %v", componentType, componentTitle))
}

func readFile(location *string) *Config {

	yamlFile, err := ioutil.ReadFile(*location)
	if err != nil {
		log.Fatalf("Failed to read config file: %s", *location)
	}

	cfg := new(Config)
	err = yaml.Unmarshal(yamlFile, cfg)

	if err != nil {
		log.Fatalf("Failed to read config file: %v", err)
	}

	return cfg

View on GitHub (pinned to 9bc7ba732d)