{"record":{"id":"cfc8e6a32688f8d7","repo":"owasp-amass/amass","slug":"failed-to-cast-the-tlscertificate-asset","errorCode":null,"errorMessage":"failed to cast the TLSCertificate asset","messagePattern":"failed to cast the TLSCertificate asset","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/plugins/horizontals/tls_cert.go","lineNumber":31,"sourceCode":"\tdbt \"github.com/owasp-amass/asset-db/types\"\n\toam \"github.com/owasp-amass/open-asset-model\"\n\toamcert \"github.com/owasp-amass/open-asset-model/certificate\"\n\toamdns \"github.com/owasp-amass/open-asset-model/dns\"\n)\n\ntype horTlsCert struct {\n\tname   string\n\tplugin *horizPlugin\n}\n\nfunc (h *horTlsCert) Name() string {\n\treturn h.name\n}\n\nfunc (h *horTlsCert) check(e *et.Event) error {\n\tc, ok := e.Entity.Asset.(*oamcert.TLSCertificate)\n\tif !ok {\n\t\treturn errors.New(\"failed to cast the TLSCertificate asset\")\n\t}\n\n\t// check if scope expansion is allowed\n\tif e.Session.Config().Rigid {\n\t\treturn nil\n\t}\n\n\tif orgs, err := h.lookup(e.Session, e.Entity); err == nil && len(orgs) > 0 {\n\t\th.process(e, c, orgs)\n\t}\n\treturn nil\n}\n\nfunc (h *horTlsCert) lookup(sess et.Session, tlsent *dbt.Entity) ([]*dbt.Entity, error) {\n\tcr, err := h.plugin.getContactRecord(sess, tlsent, \"subject_contact\")\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to obtain the subject contact record\")\n\t}","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/plugins/horizontals/tls_cert.go#L13-L49","documentation":"The horizontals TLS certificate handler's check() method is invoked for every event it subscribes to, and asserts e.Entity.Asset to *oamcert.TLSCertificate. When the event carries any other asset type, the assertion fails and this error is returned, aborting processing of that event. It means the plugin's event filter routed a non-TLS-certificate entity into the handler.","triggerScenarios":"An event whose Entity.Asset is not *oamcert.TLSCertificate reaches horTlsCert.check — typically because the event subscription/topic matches multiple asset types or a new TLS-related relation was added without filtering.","commonSituations":"Custom event handlers subscribing to broad output topics; middleware emitting TLS entities with a different asset struct; library version changes to the oamcert.TLSCertificate type.","solutions":["Check the event type in check(): if _, ok := e.Entity.Asset.(*oamcert.TLSCertificate); !ok { return nil } — i.e. treat mismatch as 'not for me' rather than an error","Narrow the plugin's event subscription so only TLSCertificate events invoke check()","Audit upstream producers of TLS events to confirm they always set Asset to *oamcert.TLSCertificate"],"exampleFix":"// before\nc, ok := e.Entity.Asset.(*oamcert.TLSCertificate)\nif !ok {\n\treturn errors.New(\"failed to cast the TLSCertificate asset\")\n}\n\n// after\nc, ok := e.Entity.Asset.(*oamcert.TLSCertificate)\nif !ok {\n\treturn nil\n}","handlingStrategy":"type-guard","validationCode":"if _, ok := e.Entity.Asset.(*oamcert.TLSCertificate); !ok {\n\treturn nil\n}","typeGuard":"func asTLSCert(e *et.Event) (*oamcert.TLSCertificate, bool) {\n\tc, ok := e.Entity.Asset.(*oamcert.TLSCertificate)\n\treturn c, ok\n}","tryCatchPattern":"if err := h.check(ev); err != nil {\n\tif strings.Contains(err.Error(), \"failed to cast\") {\n\t\tcontinue // unrelated asset type\n\t}\n\tlog.Error(err)\n}","preventionTips":["Treat cast failure as 'event not for this handler' and return nil","Subscribe only to the specific event topics for TLS certificates","Add unit tests feeding wrong-type events to confirm handlers ignore them"],"tags":["go","type-assertion","tls-certificate"],"backgroundTag":"type-mismatch","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}