{"record":{"id":"58fc1e7a36a435d8","repo":"jackwener/OpenCLI","slug":"note-must-be-300-characters-or-fewer-for-linkedi","errorCode":null,"errorMessage":"--note must be 300 characters or fewer for LinkedIn connection requests","messagePattern":"--note must be 300 characters or fewer for LinkedIn connection requests","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/connect.js","lineNumber":83,"sourceCode":"        return '';\n    }\n}\n\nfunction requireStringArg(args, key, label = key) {\n    const value = normalizeWhitespace(args[key]);\n    if (!value) throw new ArgumentError(`${label} is required`);\n    return value;\n}\n\nfunction requireLinkedInProfileUrl(value, label) {\n    const url = canonicalizeLinkedInProfileUrl(value);\n    if (!url) throw new ArgumentError(`${label} must be an exact https://www.linkedin.com/in/<profile>/ URL`);\n    return url;\n}\n\nfunction clampNote(note) {\n    const value = normalizeWhitespace(note);\n    if (value.length > 300) throw new ArgumentError('--note must be 300 characters or fewer for LinkedIn connection requests');\n    return value;\n}\n\nfunction canonicalizeLinkedInInviteUrl(value) {\n    try {\n        const url = new URL(normalizeWhitespace(value), 'https://www.linkedin.com');\n        if (url.protocol !== 'https:' || url.username || url.password || url.port || !isLinkedInHost(url.hostname)) return '';\n        if (!/^\\/preload\\/custom-invite\\/?$/i.test(url.pathname)) return '';\n        url.hostname = 'www.linkedin.com';\n        url.hash = '';\n        if (!url.pathname.endsWith('/')) url.pathname += '/';\n        return url.toString();\n    }\n    catch {\n        return '';\n    }\n}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/connect.js#L65-L101","documentation":"clampNote enforces LinkedIn's 300-character limit on connection request notes. If the whitespace-normalized --note exceeds 300 characters it throws ArgumentError instead of silently truncating, since a silently cut note could change the intended message.","triggerScenarios":"Passing --note with a message longer than 300 characters after whitespace normalization.","commonSituations":"Programmatically generating notes from templates without checking length; notes including personalized greetings that push past the limit; LinkedIn raising/lowering the limit in the UI while the library keeps 300.","solutions":["Shorten the --note to 300 characters or fewer before running the command","Count the note length in your wrapper (after whitespace trimming) and reject early","Generate dynamic notes with a template that truncates or composes within the budget","Omit --note entirely to send a note-less connection request"],"exampleFix":"// before\n--note \"Hi Jane, I really enjoyed ... (350 chars of text) ...\"\n// after\n--note \"Hi Jane, enjoyed your talk on X — would love to connect.\"","handlingStrategy":"validation","validationCode":"const note = (args.note || '').trim();\nif (note.length > 300) throw new Error(`--note is ${note.length} chars; max is 300`);","typeGuard":"function isWithinNoteLimit(note, max = 300) { return typeof note === 'string' && note.trim().length <= max; }","tryCatchPattern":"try { await runConnect(args); } catch (e) { if (String(e.message).includes('300 characters')) { console.error('Shorten --note to <= 300 chars'); } else { throw e; } }","preventionTips":["Trim/normalize whitespace and check length before invoking","Cap generated/template notes at ~280 chars to leave headroom","Omit --note when no meaningful message is needed","Add a length assertion in tests for note templates"],"tags":["cli","validation","linkedin"],"backgroundTag":"argument-length-limit-exceeded","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}