Grunt watch warning: EPERM, operation not permitted
Asked Answered
S

3

13

I have a very annoying problem with gruntjs and grunt-contrib-watch plugin. After some time, I can not define, it may be half an hour or two hours of work (it's random) the console spits out this error:

Running "watch" task
Waiting...Warning: EPERM, operation not permitted 'C:\dev\project\app\index.html~RF97bf99.TMP'

it repeats ~50 times, and next this:

Warning: An error occurred while processing a template (An error occurred while processing a templat
e (Maximum call stack size exceeded).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (Maximum call stack size exceeded).).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (An error occurred while processing a template (Max
imum call stack size exceeded).).).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (An error occurred while processing a template (An
error occurred while processing a template (Maximum call stack size exceeded).).).).).

My Grunfile.js:

'use strict';

module.exports = function (grunt) {

    // Load all grunt tasks
    require('load-grunt-tasks')(grunt);
    // Show elapsed time at the end
    require('time-grunt')(grunt);

    grunt.initConfig({
        // Project settings
        project: {
            app: 'app',
            dist: 'dist'
        },
        bootstrap: {
            src: 'bower_components/sass-bootstrap',
            pkg: grunt.file.readJSON('bower_components/sass-bootstrap/package.json'),
            banner: '/*!\n' +
                    ' * Bootstrap v<%= bootstrap.pkg.version %> by @fat and @mdo\n' +
                    ' * Copyright <%= grunt.template.today("yyyy") %> <%= bootstrap.pkg.author %>\n' +
                    ' * Licensed under <%= _.pluck(bootstrap.pkg.licenses, "url").join(", ") %>\n' +
                    ' *\n' +
                    ' * Designed and built with all the love in the world by @mdo and @fat.\n' +
                    ' */\n\n',
            jqueryCheck: 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }\n\n'
        },
        watch: {
            sass: {
                files: ['<%= project.app %>/sass/{,*/}*.scss'],
                tasks: ['sass:dev', 'autoprefixer'],
                options: {
                    spawn: false,
                    livereload: true
                },
            },
            js: {
                files: [
                    '<%= project.app %>/js/{,*/}*.js',
                    '!<%= project.app %>/js/vendor/{,*/}*.js',
                    '!<%= project.app %>/js/plugins/{,*/}*.js'
                ],
                options: {
                    livereload: true
                }
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= project.app %>/{,*/}*.html',
                    '<%= project.app %>/css/{,*/}*.css',
                    '<%= project.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
                ]
            }
        },
        connect: {
            options: {
                port: 9000,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    open: true,
                    base: '<%= project.app %>'
                }
            },
            dist: {
                options: {
                    open: true,
                    base: '<%= project.dist %>',
                    livereload: false
                }
            }
        },
        sass: {
            options: {
                includePaths: ['<%= bootstrap.src %>/lib/']
            },
            dev: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            },
            dist: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            }
        },
        autoprefixer: {
            options: {
                browsers: ['last 2 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/css/',
                    src: '{,*/}*.css',
                    dest: '<%= project.app %>/css/'
                }]
            }
        },
        concat: {
            options: {
                nonull: true,
                separator: '\n\n'
            },
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %><%= bootstrap.jqueryCheck %>'
                },
                src: [
                    '<%= bootstrap.src %>/js/transition.js',
                    // '<%= bootstrap.src %>/js/alert.js',
                    // '<%= bootstrap.src %>/js/button.js',
                    // '<%= bootstrap.src %>/js/carousel.js',
                    '<%= bootstrap.src %>/js/collapse.js',
                    '<%= bootstrap.src %>/js/dropdown.js',
                    // '<%= bootstrap.src %>/js/modal.js',
                    // '<%= bootstrap.src %>/js/tooltip.js',
                    // '<%= bootstrap.src %>/js/popover.js',
                    // '<%= bootstrap.src %>/js/scrollspy.js',
                    // '<%= bootstrap.src %>/js/tab.js',
                    // '<%= bootstrap.src %>/js/affix.js'
                ],
                dest: '<%= project.app %>/js/plugins/bootstrap.js'
            },
            plugins: {
                files: {
                    '<%= project.app %>/js/plugins.js': ['<%= project.app %>/js/plugins/bootstrap.min.js', '<%= project.app %>/js/plugins/*.min.js']
                }
            }
        },
        uglify: {
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %>'
                },
                files: {
                    '<%= project.app %>/js/plugins/bootstrap.min.js': '<%= concat.bootstrap.dest %>'
                }
            },
            all: {
                options: {
                    preserveComments: 'some',
                    report: 'min'
                },
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/js/',
                    src: ['*.js', '!plugins.js'],
                    ext: '.min.js',
                    dest: '<%= project.app %>/js/'
                }]
            }
        },
        cssmin: {
            options: {
                report: 'min'
            },
            dist: {
                expand: true,
                cwd: '<%= project.app %>/css/',
                src: ['*.css', '!*.min.css'],
                dest: '<%= cssmin.dist.cwd %>',
                ext: '.min.css'
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/img',
                    src: ['{,*/}*.{gif,jpeg,jpg,png}'],
                    dest: '<%= project.dist %>/img'
                }]
            }
        }
    });

    // Register tasks
    // ==================================================

    // Run local server
    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'connect:livereload',
            'watch'
        ]);
    });

    // Build JS
    grunt.registerTask('build-js', [
        'concat:bootstrap',
        'uglify',
        'concat:plugins'
    ]);

    // Build CSS
    grunt.registerTask('build-css', [
        'sass:dist',
        'autoprefixer',
        'cssmin'
    ]);

    // Minify images
    grunt.registerTask('test', ['imagemin']);

    // grunt.registerTask('default', ['']);

};

package.json (all dependencies are up to date):

{
  "name": "project",
  "version": "0.0.0",
  "dependencies": {},
  "devDependencies": {
    "load-grunt-tasks": "~0.2.1",
    "time-grunt": "~0.2.6",
    "grunt": "~0.4.2",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-contrib-connect": "~0.6.0",
    "grunt-autoprefixer": "~0.6.3",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-uglify": "~0.2.7",
    "grunt-contrib-cssmin": "~0.7.0",
    "grunt-sass": "~0.9.0",
    "jpegtran-bin": "~0.2.0",
    "grunt-contrib-imagemin": "~0.4.0"
  }
}

I'm on Windows 7 32-bit, gruntjs v.0.4.2, nodejs v0.10.22. Any ideas what may causes this problem? And how would I fix it? Thanks a lot.

Susceptible answered 3/1, 2014 at 11:53 Comment(0)
C
14

I had a similar problem "EPERM, operation not permitted..." and it was because i didn't opened the CMD in administrator mode. So right click on CMD and run as administrator. This solved my error.

Clynes answered 16/6, 2014 at 14:57 Comment(3)
I just had the same problem on a Linux Mint. Running the grunt task with sudo worked.Sideband
this should most likely be the accepted answer, worked well for me and solved my problem. Thank youRoving
Just running anything that errors with superuser permissions is a recipe for disaster.Chrysotile
C
2

I'm not familiar with this problem, but I think it might have something to do with the way you're using wildcards on your Gruntfile.js. A co-worker once complained that his watch task was taking an incredible amount of time to run, up to 3-4 minutes a time. He was using the syntax:

/css/{,*/}*.css

I didn't have that problem, so while making his Gruntfile.js more like mine, we found out that using:

/css/**/*.css

...solved the whole problem! All his tasks ran at less than 10 seconds.

I have made changes to your Gruntfile.js, you might want to use a diff tool to compare my version to yours and see what was changed.

I would also strongly recommend using jshint to lint the JavaScript in your project, specially the Gruntfile.js and any other configuration file important to Grunt you might have detached from your Gruntfile.js. An example here (look around the same project for more detail).

'use strict';

module.exports = function (grunt) {

    // Load all grunt tasks
    require('load-grunt-tasks')(grunt);
    // Show elapsed time at the end
    require('time-grunt')(grunt);

    grunt.initConfig({
        // Project settings
        project: {
            app: 'app',
            dist: 'dist'
        },
        bootstrap: {
            src: 'bower_components/sass-bootstrap',
            pkg: grunt.file.readJSON('bower_components/sass-bootstrap/package.json'),
            banner: '/*!\n' +
                    ' * Bootstrap v<%= bootstrap.pkg.version %> by @fat and @mdo\n' +
                    ' * Copyright <%= grunt.template.today("yyyy") %> <%= bootstrap.pkg.author %>\n' +
                    ' * Licensed under <%= _.pluck(bootstrap.pkg.licenses, "url").join(", ") %>\n' +
                    ' *\n' +
                    ' * Designed and built with all the love in the world by @mdo and @fat.\n' +
                    ' */\n\n',
            jqueryCheck: 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }\n\n'
        },
        watch: {
            sass: {
                files: ['<%= project.app %>/sass/**/*.scss'],
                tasks: ['sass:dev', 'autoprefixer'],
                options: {
                    spawn: false,
                    livereload: true
                },
            },
            js: {
                files: [
                    '<%= project.app %>/js/**/*.js',
                    '!<%= project.app %>/js/vendor/**/*.js',
                    '!<%= project.app %>/js/plugins/**/*.js'
                ],
                options: {
                    livereload: true
                }
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= project.app %>/**/*.html',
                    '<%= project.app %>/css/**/*.css',
                    '<%= project.app %>/images/**/*.{gif,jpeg,jpg,png,svg,webp}'
                ]
            }
        },
        connect: {
            options: {
                port: 9000,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    open: true,
                    base: '<%= project.app %>'
                }
            },
            dist: {
                options: {
                    open: true,
                    base: '<%= project.dist %>',
                    livereload: false
                }
            }
        },
        sass: {
            options: {
                includePaths: ['<%= bootstrap.src %>/lib/']
            },
            dev: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            },
            dist: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            }
        },
        autoprefixer: {
            options: {
                browsers: ['last 2 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/css',
                    src: '/**/*.css',
                    dest: '<%= project.app %>/css'
                }]
            }
        },
        concat: {
            options: {
                nonull: true,
                separator: '\n\n'
            },
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %><%= bootstrap.jqueryCheck %>'
                },
                src: [
                    '<%= bootstrap.src %>/js/transition.js',
                    // '<%= bootstrap.src %>/js/alert.js',
                    // '<%= bootstrap.src %>/js/button.js',
                    // '<%= bootstrap.src %>/js/carousel.js',
                    '<%= bootstrap.src %>/js/collapse.js',
                    '<%= bootstrap.src %>/js/dropdown.js'
                    // '<%= bootstrap.src %>/js/modal.js',
                    // '<%= bootstrap.src %>/js/tooltip.js',
                    // '<%= bootstrap.src %>/js/popover.js',
                    // '<%= bootstrap.src %>/js/scrollspy.js',
                    // '<%= bootstrap.src %>/js/tab.js',
                    // '<%= bootstrap.src %>/js/affix.js'
                ],
                dest: '<%= project.app %>/js/plugins/bootstrap.js'
            },
            plugins: {
                files: {
                    '<%= project.app %>/js/plugins.js': ['<%= project.app %>/js/plugins/bootstrap.min.js', '<%= project.app %>/js/plugins/*.min.js']
                }
            }
        },
        uglify: {
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %>'
                },
                files: {
                    '<%= project.app %>/js/plugins/bootstrap.min.js': '<%= concat.bootstrap.dest %>'
                }
            },
            all: {
                options: {
                    preserveComments: 'some',
                    report: 'min'
                },
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/js/',
                    src: ['*.js', '!plugins.js'],
                    ext: '.min.js',
                    dest: '<%= project.app %>/js/'
                }]
            }
        },
        cssmin: {
            options: {
                report: 'min'
            },
            dist: {
                expand: true,
                cwd: '<%= project.app %>/css/',
                src: ['*.css', '!*.min.css'],
                dest: '<%= cssmin.dist.cwd %>',
                ext: '.min.css'
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/img',
                    src: ['/**/*.{gif,jpeg,jpg,png}'],
                    dest: '<%= project.dist %>/img'
                }]
            }
        }
    });

    // Register tasks
    // ==================================================

    // Run local server
    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'connect:livereload',
            'watch'
        ]);
    });

    // Build JS
    grunt.registerTask('build-js', [
        'concat:bootstrap',
        'uglify',
        'concat:plugins'
    ]);

    // Build CSS
    grunt.registerTask('build-css', [
        'sass:dist',
        'autoprefixer',
        'cssmin'
    ]);

    // Minify images
    grunt.registerTask('test', ['imagemin']);

    // grunt.registerTask('default', ['']);

};
Condyloid answered 9/3, 2014 at 18:5 Comment(0)
S
1

On linux, change directory permissions

$ sudo chmod -R 777 name_directory
Senghor answered 15/3, 2018 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.