How to troubleshoot NPM problems

AuthorFullName__c
Patrick Russell
articleNumber
000004147
FirstPublishedDate
2018-11-13T23:41:52Z
lastModifiedDate
2021-09-27

How to troubleshoot NPM problems

Relevant versions: This information pertains to Artifactory versions 6.X and above


The npm client is used by many application pipelines to pull javascript dependencies for web UI functionality. It has several unique API calls that may cause errors if not properly handled by Artifactory. When troubleshooting these errors, it's best to compare what is supposed to happen when these calls are executed against what your system is currently experiencing. You can eliminate a great deal of noise by simulating each step your client is taking and examining what HTTP error code is sent by Artifactory.

In general, these are the error codes you might encounter and where you should explore for answers/solutions next:

401: Authentication issue, meaning the user did not use the right username / password 
403: Authorization issue, meaning the user does not have access to the requested resource
404: Resource not found, check repository for resource
400: Incorrect request, use cURL to get reason phrase
50X: Server problem, examine the artifactory-service.log (7.X) or artifactory.log (6.X)

Using curl

The libcurl terminal application can run basic REST API commands such as GET or PUT options. Your Artifactory request logs will display the exact API commands your Docker client uses. You can use the one that is failing (as listed in the request.log file) or use one of these examples below to try to acquire further information on the problem being encountered, as well as possible next steps.

Basic usage (with #comments):

curl -uadmin #Artifactory-username -vvv #verbosy -k #ignore-insecure-SSL -XGET #GET-request http://<artifactory.com>/artifactory/api/system/ping

cURL uses GET requests by default. Other commands, like PUT, require the --data field, along with a (typically, JSON) data payload. Here's a sample PUT command:

curl -uadmin:password -XPUT -H"Content-type: Application/json" --data '{"name":"test-group"}' http://<artifactory.com>/artifactory/api/security/groups/test-group


 

NPM Login

When you run an npm login, the npm client will prompt you for your information:


jfrog@jfrog:~/development/npm$ npm login
Username: admin
Password: 
Email: (this IS public) admin@admin.com


On the backend npm will run a PUT request to retrieve a token for future use:

20180523134454|10365|REQUEST|127.0.0.1|anonymous|PUT|/api/npm/npm/-/user/org.couchdb.user:admin|HTTP/1.1|201|153

 
NPM Install (Non-scoped)

When you run an npm install, the npm client obtains metadata then returns the package:

npm install foobar

1. The NPM client requests metadata on the package:

20180523134502|2498|REQUEST|127.0.0.1|admin|GET|/api/npm/npm/foobar|HTTP/1.1|200|0

2. The metadata contains the download link for the tar.gz file:

20180523134503|386|REQUEST|127.0.0.1|admin|GET|/api/npm/npm/foobar/-/foobar-1.1.0.tgz|HTTP/1.1|200|10240


as well as dependency files:

20180523134506|26|REQUEST|127.0.0.1|admin|GET|/api/npm/npm/busybox/-/busybox-2017.3.22.tgz|HTTP/1.1|200|518376

The metadata is pulled from a “package.json” file found in each NPM .tgz file:

{
    "name": "@types/webpack",
    "version": "3.8.5",
    "description": "TypeScript definitions for webpack",
    "license": "MIT",
    "contributors": [
[...]
"main": "",
    "repository": {
        "type": "git",
        "url": "https://www.github.com/DefinitelyTyped/DefinitelyTyped.git"
    },
"scripts": {},
    "dependencies": {
        "@types/tapable": "*",
        "@types/uglify-js": "*",
        "@types/node": "*"
    },
    "typesPublisherContentHash": "9cb451892d84836f57c4925bdc1308f145e527eed87c3610683ada4330d844ca",
    "typeScriptVersion": "2.0"
}

 
NPM install (Scoped Packages)
npm install @angular/cli

For scoped packages (@angular/router), npm install uses an encoded slash for the “/” between the scope and the package name. This will be displayed as %2f in your Artifactory request logs:

20180731002214|166|REQUEST|127.0.0.1|admin|GET|/api/npm/npm/@angular%2fcli|HTTP/1.1|200|0
20180731002214|190|REQUEST|127.0.0.1|admin|GET|/api/npm/npm/@angular/cli/-/cli-6.1.1.tgz|HTTP/1.1|200|128696


There are two (2) locations where the encoded slash may fail. The first is on the Artifactory JVM options (“-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true”), which has enables by default. The second is on reverse proxies. Artifactory’s self-generated reverse proxy settings have the correct configuration to keep the slash unencoded:
 

 ##The “/” in the proxy_pass line forces Nginx / Apache to not decode encoded characters
proxy_pass          http://localhost:8081/artifactory/;
NPM Publish

To publish npm packages to Artifactory, you'll need to configure your package.json to point to your Artifactory npm repository:

{
  "name": "test-package",
  "version": "0.0.16",
  "description": "hahahahah",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Pat",
  "license": "ISC",
  "publishConfig": {
    "registry": "http://localhost:8081/artifactory/api/npm/npm/"
  },
  "dependencies": {
    "angular": "^1.6.4",
    "busybox": "^2017.3.22",
    "clone": "^2.1.1",
    "uglify-js": "^2.7.5"
  },
  "devDependencies": {},
  "maintainers" : [
    {"name":"jimmy", "email":"jim@jimmy.com"},
    {"name":"Frank","email":"frank@west.com"}]
}


After doing so, you can run npm publish to deploy a .tar.gz file to the local repository:

npm publish

[request.log]
20180524084923|96|REQUEST|127.0.0.1|admin|PUT|/api/npm/npm/test-package|HTTP/1.1|201|1695
 


Here is an example curl command which simulates a publish. You need to manually download an NPM .tar.gz file for this command to work:

curl -XPUT -u admin -T test-package-1.0.tgz http://<artifactory.com>/artifactory/api/npm/npm-local/test-package​​​​​​​

 
Dependency Rewrites

A common setting for npm is the Enable Dependency Rewrite option for virtual repositories. This allows Artifactory to cache GitHub metadata associated with npm packages and locally serve the content. When a remote repository is established as the dependency cache, an _external folder will be created that stores GitHub .tar.gz files:

User-added image

From time to time, you may find that Artifactory is unable to reach GitHub. If you see such occurrences in your logs, consider disabling Dependency Rewrites to see if this resolves that problem.