{"record":{"id":"2e639bdba2b5f8eb","repo":"owasp-amass/amass","slug":"failed-to-cast-the-domainrecord","errorCode":null,"errorMessage":"failed to cast the DomainRecord","messagePattern":"failed to cast the DomainRecord","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/plugins/horizontals/plugin.go","lineNumber":481,"sourceCode":"\t\t\tif a, conf := sess.Scope().IsAssetInScope(ent.Asset, econf); conf >= econf {\n\t\t\t\tif strings.EqualFold(a.Key(), ent.Asset.Key()) {\n\t\t\t\t\t_ = sess.Backlog().Enqueue(ent)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *horizPlugin) enqueueIfOutOfScope(sess et.Session, ent *dbt.Entity) {\n\tif !h.isEntityInScope(sess, ent) {\n\t\th.addToScopeAndEnqueue(sess, ent)\n\t}\n}\n\nfunc (h *horizPlugin) getRegisteredDomainEntity(sess et.Session, record *dbt.Entity) (*dbt.Entity, error) {\n\tdr, valid := record.Asset.(*oamreg.DomainRecord)\n\tif !valid {\n\t\treturn nil, errors.New(\"failed to cast the DomainRecord\")\n\t}\n\n\tctx, cancel := context.WithTimeout(sess.Ctx(), 30*time.Second)\n\tdefer cancel()\n\n\tif ents, err := sess.DB().FindEntitiesByContent(ctx, oam.FQDN, time.Time{}, 1, dbt.ContentFilters{\n\t\t\"name\": dr.Domain,\n\t}); err == nil && len(ents) == 1 {\n\t\treturn ents[0], nil\n\t}\n\n\treturn nil, fmt.Errorf(\"failed to obtain the registered domain name FQDN for: %s\", dr.Domain)\n}\n\nfunc (h *horizPlugin) getRegisteredNetblockEntity(sess et.Session, record *dbt.Entity) (*dbt.Entity, error) {\n\tiprec, valid := record.Asset.(*oamreg.IPNetRecord)\n\tif !valid {\n\t\treturn nil, errors.New(\"failed to cast the IPNetRecord\")","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/plugins/horizontals/plugin.go#L463-L499","documentation":"getRegisteredDomainEntity expects record.Asset to hold an *oamreg.DomainRecord so it can look up the registered domain entity in the graph database. When the asset stored on the Entity is any other type, the Go type assertion fails and this sentinel error is returned. It indicates the caller passed an entity whose asset is not a DomainRecord (e.g. an FQDN, IPAddress, or other asset kind) to a DomainRecord-only code path.","triggerScenarios":"processInScope or processDomainRecord passes an entity whose Asset field is not *oamreg.DomainRecord into getRegisteredDomainEntity — e.g. an event tagged as a domain-related relation carries a different asset type, or a DB query returns entities whose Asset was not reconstructed as DomainRecord.","commonSituations":"Adding a new event/relation type that routes into the horizontals plugin without updating its asset dispatch; database reload where entity assets deserialize to a generic type; plugins emitting records with the wrong asset struct.","solutions":["Before calling getRegisteredDomainEntity, assert record.Asset.(*oamreg.DomainRecord) and skip/return nil if it fails","Check the upstream producer: ensure the event chain only routes *oamreg.DomainRecord assets into processInScope/processDomainRecord","If entities come from DB queries, verify the asset reconstruction maps content of type oam.DomainRecord back to *oamreg.DomainRecord"],"exampleFix":"// before\nents, err := h.getRegisteredDomainEntity(sess, record)\nif err != nil {\n\treturn err\n}\n\n// after\nif _, ok := record.Asset.(*oamreg.DomainRecord); !ok {\n\treturn nil\n}\nents, err := h.getRegisteredDomainEntity(sess, record)","handlingStrategy":"type-guard","validationCode":"if _, ok := record.Asset.(*oamreg.DomainRecord); !ok {\n\treturn nil // not a DomainRecord; skip\n}","typeGuard":"func isDomainRecord(a interface{}) (*oamreg.DomainRecord, bool) {\n\tdr, ok := a.(*oamreg.DomainRecord)\n\treturn dr, ok\n}","tryCatchPattern":"if err != nil {\n\tvar castErr *assertErr\n\tif errors.As(err, &castErr) {\n\t\treturn nil // skip wrong-type entities\n\t}\n\treturn err\n}","preventionTips":["Always type-assert entities before passing them to cast-specific helpers","Log skipped mismatches at debug level to catch routing bugs","Keep event topics narrow to the asset type each handler expects"],"tags":["go","type-assertion","asset-type"],"backgroundTag":"type-mismatch","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}